xref: /petsc/src/tao/interface/taosolver.c (revision a0c1843407dcb9509b3c2f65f771c3f8bf8d8806)
1 #include <petsc/private/taoimpl.h> /*I "petsctao.h" I*/
2 #include <petsc/private/snesimpl.h>
3 
4 PetscBool TaoRegisterAllCalled = PETSC_FALSE;
5 PetscFunctionList TaoList = NULL;
6 
7 PetscClassId TAO_CLASSID;
8 
9 PetscLogEvent TAO_Solve;
10 PetscLogEvent TAO_ObjectiveEval;
11 PetscLogEvent TAO_GradientEval;
12 PetscLogEvent TAO_ObjGradEval;
13 PetscLogEvent TAO_HessianEval;
14 PetscLogEvent TAO_JacobianEval;
15 PetscLogEvent TAO_ConstraintsEval;
16 
17 const char *TaoSubSetTypes[] = {"subvec","mask","matrixfree","TaoSubSetType","TAO_SUBSET_",NULL};
18 
19 struct _n_TaoMonitorDrawCtx {
20   PetscViewer viewer;
21   PetscInt    howoften;  /* when > 0 uses iteration % howoften, when negative only final solution plotted */
22 };
23 
24 static PetscErrorCode KSPPreSolve_TAOEW_Private(KSP ksp, Vec b, Vec x, Tao tao)
25 {
26   SNES snes_ewdummy = tao->snes_ewdummy;
27 
28   PetscFunctionBegin;
29   if (!snes_ewdummy) PetscFunctionReturn(0);
30   /* populate snes_ewdummy struct values used in KSPPreSolve_SNESEW */
31   snes_ewdummy->vec_func = b;
32   snes_ewdummy->rtol = tao->gttol;
33   snes_ewdummy->iter = tao->niter;
34   PetscCall(VecNorm(b,NORM_2,&snes_ewdummy->norm));
35   PetscCall(KSPPreSolve_SNESEW(ksp,b,x,snes_ewdummy));
36   snes_ewdummy->vec_func = NULL;
37   PetscFunctionReturn(0);
38 }
39 
40 static PetscErrorCode KSPPostSolve_TAOEW_Private(KSP ksp, Vec b, Vec x, Tao tao)
41 {
42   SNES snes_ewdummy = tao->snes_ewdummy;
43 
44   PetscFunctionBegin;
45   if (!snes_ewdummy) PetscFunctionReturn(0);
46   PetscCall(KSPPostSolve_SNESEW(ksp,b,x,snes_ewdummy));
47   PetscFunctionReturn(0);
48 }
49 
50 static PetscErrorCode TaoSetUpEW_Private(Tao tao)
51 {
52   SNESKSPEW  *kctx;
53   const char *ewprefix;
54 
55   PetscFunctionBegin;
56   if (!tao->ksp) PetscFunctionReturn(0);
57   if (tao->ksp_ewconv) {
58     if (!tao->snes_ewdummy) PetscCall(SNESCreate(PetscObjectComm((PetscObject)tao),&tao->snes_ewdummy));
59     tao->snes_ewdummy->ksp_ewconv = PETSC_TRUE;
60     PetscCall(KSPSetPreSolve(tao->ksp,(PetscErrorCode (*)(KSP,Vec,Vec,void*))KSPPreSolve_TAOEW_Private,tao));
61     PetscCall(KSPSetPostSolve(tao->ksp,(PetscErrorCode (*)(KSP,Vec,Vec,void*))KSPPostSolve_TAOEW_Private,tao));
62 
63     PetscCall(KSPGetOptionsPrefix(tao->ksp,&ewprefix));
64     kctx = (SNESKSPEW*)tao->snes_ewdummy->kspconvctx;
65     PetscCall(SNESEWSetFromOptions_Private(kctx,PetscObjectComm((PetscObject)tao),ewprefix));
66   } else PetscCall(SNESDestroy(&tao->snes_ewdummy));
67   PetscFunctionReturn(0);
68 }
69 
70 /*@
71   TaoCreate - Creates a TAO solver
72 
73   Collective
74 
75   Input Parameter:
76 . comm - MPI communicator
77 
78   Output Parameter:
79 . newtao - the new Tao context
80 
81   Available methods include:
82 +    nls - Newton's method with line search for unconstrained minimization
83 .    ntr - Newton's method with trust region for unconstrained minimization
84 .    ntl - Newton's method with trust region, line search for unconstrained minimization
85 .    lmvm - Limited memory variable metric method for unconstrained minimization
86 .    cg - Nonlinear conjugate gradient method for unconstrained minimization
87 .    nm - Nelder-Mead algorithm for derivate-free unconstrained minimization
88 .    tron - Newton Trust Region method for bound constrained minimization
89 .    gpcg - Newton Trust Region method for quadratic bound constrained minimization
90 .    blmvm - Limited memory variable metric method for bound constrained minimization
91 .    lcl - Linearly constrained Lagrangian method for pde-constrained minimization
92 -    pounders - Model-based algorithm for nonlinear least squares
93 
94    Options Database Keys:
95 .   -tao_type - select which method TAO should use
96 
97    Level: beginner
98 
99 .seealso: `TaoSolve()`, `TaoDestroy()`
100 @*/
101 PetscErrorCode TaoCreate(MPI_Comm comm, Tao *newtao)
102 {
103   Tao            tao;
104 
105   PetscFunctionBegin;
106   PetscValidPointer(newtao,2);
107   PetscCall(TaoInitializePackage());
108   PetscCall(TaoLineSearchInitializePackage());
109   PetscCall(PetscHeaderCreate(tao,TAO_CLASSID,"Tao","Optimization solver","Tao",comm,TaoDestroy,TaoView));
110 
111   /* Set non-NULL defaults */
112   tao->ops->convergencetest = TaoDefaultConvergenceTest;
113 
114   tao->max_it    = 10000;
115   tao->max_funcs = -1;
116 #if defined(PETSC_USE_REAL_SINGLE)
117   tao->gatol     = 1e-5;
118   tao->grtol     = 1e-5;
119   tao->crtol     = 1e-5;
120   tao->catol     = 1e-5;
121 #else
122   tao->gatol     = 1e-8;
123   tao->grtol     = 1e-8;
124   tao->crtol     = 1e-8;
125   tao->catol     = 1e-8;
126 #endif
127   tao->gttol     = 0.0;
128   tao->steptol   = 0.0;
129   tao->trust0    = PETSC_INFINITY;
130   tao->fmin      = PETSC_NINFINITY;
131 
132   tao->hist_reset  = PETSC_TRUE;
133 
134   PetscCall(TaoResetStatistics(tao));
135   *newtao = tao;
136   PetscFunctionReturn(0);
137 }
138 
139 /*@
140   TaoSolve - Solves an optimization problem min F(x) s.t. l <= x <= u
141 
142   Collective on Tao
143 
144   Input Parameters:
145 . tao - the Tao context
146 
147   Notes:
148   The user must set up the Tao with calls to TaoSetSolution(),
149   TaoSetObjective(),
150   TaoSetGradient(), and (if using 2nd order method) TaoSetHessian().
151 
152   You should call TaoGetConvergedReason() or run with -tao_converged_reason to determine if the optimization algorithm actually succeeded or
153   why it failed.
154 
155   Level: beginner
156 
157 .seealso: `TaoCreate()`, `TaoSetObjective()`, `TaoSetGradient()`, `TaoSetHessian()`, `TaoGetConvergedReason()`
158  @*/
159 PetscErrorCode TaoSolve(Tao tao)
160 {
161   static PetscBool set = PETSC_FALSE;
162 
163   PetscFunctionBegin;
164   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
165   PetscCall(PetscCitationsRegister("@TechReport{tao-user-ref,\n"
166                                    "title   = {Toolkit for Advanced Optimization (TAO) Users Manual},\n"
167                                    "author  = {Todd Munson and Jason Sarich and Stefan Wild and Steve Benson and Lois Curfman McInnes},\n"
168                                    "Institution = {Argonne National Laboratory},\n"
169                                    "Year   = 2014,\n"
170                                    "Number = {ANL/MCS-TM-322 - Revision 3.5},\n"
171                                    "url    = {https://www.mcs.anl.gov/research/projects/tao/}\n}\n",&set));
172   tao->header_printed = PETSC_FALSE;
173   PetscCall(TaoSetUp(tao));
174   PetscCall(TaoResetStatistics(tao));
175   if (tao->linesearch) {
176     PetscCall(TaoLineSearchReset(tao->linesearch));
177   }
178 
179   PetscCall(PetscLogEventBegin(TAO_Solve,tao,0,0,0));
180   if (tao->ops->solve) PetscCall((*tao->ops->solve)(tao));
181   PetscCall(PetscLogEventEnd(TAO_Solve,tao,0,0,0));
182 
183   PetscCall(VecViewFromOptions(tao->solution,(PetscObject)tao,"-tao_view_solution"));
184 
185   tao->ntotalits += tao->niter;
186   PetscCall(TaoViewFromOptions(tao,NULL,"-tao_view"));
187 
188   if (tao->printreason) {
189     if (tao->reason > 0) {
190       PetscCall(PetscPrintf(((PetscObject)tao)->comm,"TAO solve converged due to %s iterations %" PetscInt_FMT "\n",TaoConvergedReasons[tao->reason],tao->niter));
191     } else {
192       PetscCall(PetscPrintf(((PetscObject)tao)->comm,"TAO solve did not converge due to %s iteration %" PetscInt_FMT "\n",TaoConvergedReasons[tao->reason],tao->niter));
193     }
194   }
195   PetscFunctionReturn(0);
196 }
197 
198 /*@
199   TaoSetUp - Sets up the internal data structures for the later use
200   of a Tao solver
201 
202   Collective on tao
203 
204   Input Parameters:
205 . tao - the TAO context
206 
207   Notes:
208   The user will not need to explicitly call TaoSetUp(), as it will
209   automatically be called in TaoSolve().  However, if the user
210   desires to call it explicitly, it should come after TaoCreate()
211   and any TaoSetSomething() routines, but before TaoSolve().
212 
213   Level: advanced
214 
215 .seealso: `TaoCreate()`, `TaoSolve()`
216 @*/
217 PetscErrorCode TaoSetUp(Tao tao)
218 {
219   PetscFunctionBegin;
220   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
221   if (tao->setupcalled) PetscFunctionReturn(0);
222   PetscCall(TaoSetUpEW_Private(tao));
223   PetscCheck(tao->solution,PetscObjectComm((PetscObject)tao),PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetSolution");
224   if (tao->ops->setup) PetscCall((*tao->ops->setup)(tao));
225   tao->setupcalled = PETSC_TRUE;
226   PetscFunctionReturn(0);
227 }
228 
229 /*@C
230   TaoDestroy - Destroys the TAO context that was created with
231   TaoCreate()
232 
233   Collective on Tao
234 
235   Input Parameter:
236 . tao - the Tao context
237 
238   Level: beginner
239 
240 .seealso: `TaoCreate()`, `TaoSolve()`
241 @*/
242 PetscErrorCode TaoDestroy(Tao *tao)
243 {
244   PetscFunctionBegin;
245   if (!*tao) PetscFunctionReturn(0);
246   PetscValidHeaderSpecific(*tao,TAO_CLASSID,1);
247   if (--((PetscObject)*tao)->refct > 0) {*tao = NULL;PetscFunctionReturn(0);}
248 
249   if ((*tao)->ops->destroy) {
250     PetscCall((*((*tao))->ops->destroy)(*tao));
251   }
252   PetscCall(KSPDestroy(&(*tao)->ksp));
253   PetscCall(SNESDestroy(&(*tao)->snes_ewdummy));
254   PetscCall(TaoLineSearchDestroy(&(*tao)->linesearch));
255 
256   if ((*tao)->ops->convergencedestroy) {
257     PetscCall((*(*tao)->ops->convergencedestroy)((*tao)->cnvP));
258     if ((*tao)->jacobian_state_inv) {
259       PetscCall(MatDestroy(&(*tao)->jacobian_state_inv));
260     }
261   }
262   PetscCall(VecDestroy(&(*tao)->solution));
263   PetscCall(VecDestroy(&(*tao)->gradient));
264   PetscCall(VecDestroy(&(*tao)->ls_res));
265 
266   if ((*tao)->gradient_norm) {
267     PetscCall(PetscObjectDereference((PetscObject)(*tao)->gradient_norm));
268     PetscCall(VecDestroy(&(*tao)->gradient_norm_tmp));
269   }
270 
271   PetscCall(VecDestroy(&(*tao)->XL));
272   PetscCall(VecDestroy(&(*tao)->XU));
273   PetscCall(VecDestroy(&(*tao)->IL));
274   PetscCall(VecDestroy(&(*tao)->IU));
275   PetscCall(VecDestroy(&(*tao)->DE));
276   PetscCall(VecDestroy(&(*tao)->DI));
277   PetscCall(VecDestroy(&(*tao)->constraints));
278   PetscCall(VecDestroy(&(*tao)->constraints_equality));
279   PetscCall(VecDestroy(&(*tao)->constraints_inequality));
280   PetscCall(VecDestroy(&(*tao)->stepdirection));
281   PetscCall(MatDestroy(&(*tao)->hessian_pre));
282   PetscCall(MatDestroy(&(*tao)->hessian));
283   PetscCall(MatDestroy(&(*tao)->ls_jac));
284   PetscCall(MatDestroy(&(*tao)->ls_jac_pre));
285   PetscCall(MatDestroy(&(*tao)->jacobian_pre));
286   PetscCall(MatDestroy(&(*tao)->jacobian));
287   PetscCall(MatDestroy(&(*tao)->jacobian_state_pre));
288   PetscCall(MatDestroy(&(*tao)->jacobian_state));
289   PetscCall(MatDestroy(&(*tao)->jacobian_state_inv));
290   PetscCall(MatDestroy(&(*tao)->jacobian_design));
291   PetscCall(MatDestroy(&(*tao)->jacobian_equality));
292   PetscCall(MatDestroy(&(*tao)->jacobian_equality_pre));
293   PetscCall(MatDestroy(&(*tao)->jacobian_inequality));
294   PetscCall(MatDestroy(&(*tao)->jacobian_inequality_pre));
295   PetscCall(ISDestroy(&(*tao)->state_is));
296   PetscCall(ISDestroy(&(*tao)->design_is));
297   PetscCall(VecDestroy(&(*tao)->res_weights_v));
298   PetscCall(TaoCancelMonitors(*tao));
299   if ((*tao)->hist_malloc) {
300     PetscCall(PetscFree4((*tao)->hist_obj,(*tao)->hist_resid,(*tao)->hist_cnorm,(*tao)->hist_lits));
301   }
302   if ((*tao)->res_weights_n) {
303     PetscCall(PetscFree((*tao)->res_weights_rows));
304     PetscCall(PetscFree((*tao)->res_weights_cols));
305     PetscCall(PetscFree((*tao)->res_weights_w));
306   }
307   PetscCall(PetscHeaderDestroy(tao));
308   PetscFunctionReturn(0);
309 }
310 
311 /*@
312    TaoKSPSetUseEW - Sets SNES use Eisenstat-Walker method for
313    computing relative tolerance for linear solvers.
314 
315    Logically Collective on TAO
316 
317    Input Parameters:
318 +  tao - Tao context
319 -  flag - PETSC_TRUE or PETSC_FALSE
320 
321    Notes:
322    See SNESKSPSetUseEW() for customization details.
323 
324    Level: advanced
325 
326    Reference:
327    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
328    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
329 
330 .seealso: `SNESKSPSetUseEW()`
331 @*/
332 PetscErrorCode  TaoKSPSetUseEW(Tao tao,PetscBool flag)
333 {
334   PetscFunctionBegin;
335   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
336   PetscValidLogicalCollectiveBool(tao,flag,2);
337   tao->ksp_ewconv = flag;
338   PetscFunctionReturn(0);
339 }
340 
341 /*@
342   TaoSetFromOptions - Sets various Tao parameters from user
343   options.
344 
345   Collective on Tao
346 
347   Input Parameter:
348 . tao - the Tao solver context
349 
350   options Database Keys:
351 + -tao_type <type> - The algorithm that TAO uses (lmvm, nls, etc.)
352 . -tao_gatol <gatol> - absolute error tolerance for ||gradient||
353 . -tao_grtol <grtol> - relative error tolerance for ||gradient||
354 . -tao_gttol <gttol> - reduction of ||gradient|| relative to initial gradient
355 . -tao_max_it <max> - sets maximum number of iterations
356 . -tao_max_funcs <max> - sets maximum number of function evaluations
357 . -tao_fmin <fmin> - stop if function value reaches fmin
358 . -tao_steptol <tol> - stop if trust region radius less than <tol>
359 . -tao_trust0 <t> - initial trust region radius
360 . -tao_monitor - prints function value and residual at each iteration
361 . -tao_smonitor - same as tao_monitor, but truncates very small values
362 . -tao_cmonitor - prints function value, residual, and constraint norm at each iteration
363 . -tao_view_solution - prints solution vector at each iteration
364 . -tao_view_ls_residual - prints least-squares residual vector at each iteration
365 . -tao_view_stepdirection - prints step direction vector at each iteration
366 . -tao_view_gradient - prints gradient vector at each iteration
367 . -tao_draw_solution - graphically view solution vector at each iteration
368 . -tao_draw_step - graphically view step vector at each iteration
369 . -tao_draw_gradient - graphically view gradient at each iteration
370 . -tao_fd_gradient - use gradient computed with finite differences
371 . -tao_fd_hessian - use hessian computed with finite differences
372 . -tao_mf_hessian - use matrix-free hessian computed with finite differences
373 . -tao_cancelmonitors - cancels all monitors (except those set with command line)
374 . -tao_view - prints information about the Tao after solving
375 - -tao_converged_reason - prints the reason TAO stopped iterating
376 
377   Notes:
378   To see all options, run your program with the -help option or consult the
379   user's manual. Should be called after TaoCreate() but before TaoSolve()
380 
381   Level: beginner
382 @*/
383 PetscErrorCode TaoSetFromOptions(Tao tao)
384 {
385   TaoType        default_type = TAOLMVM;
386   char           type[256], monfilename[PETSC_MAX_PATH_LEN];
387   PetscViewer    monviewer;
388   PetscBool      flg;
389   MPI_Comm       comm;
390 
391   PetscFunctionBegin;
392   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
393   PetscCall(PetscObjectGetComm((PetscObject)tao,&comm));
394 
395   /* So no warnings are given about unused options */
396   PetscCall(PetscOptionsHasName(((PetscObject)tao)->options,((PetscObject)tao)->prefix,"-tao_ls_type",&flg));
397 
398   PetscObjectOptionsBegin((PetscObject)tao);
399   {
400     if (((PetscObject)tao)->type_name) default_type = ((PetscObject)tao)->type_name;
401     /* Check for type from options */
402     PetscCall(PetscOptionsFList("-tao_type","Tao Solver type","TaoSetType",TaoList,default_type,type,256,&flg));
403     if (flg) {
404       PetscCall(TaoSetType(tao,type));
405     } else if (!((PetscObject)tao)->type_name) {
406       PetscCall(TaoSetType(tao,default_type));
407     }
408 
409     PetscCall(PetscOptionsReal("-tao_catol","Stop if constraints violations within","TaoSetConstraintTolerances",tao->catol,&tao->catol,&flg));
410     if (flg) tao->catol_changed = PETSC_TRUE;
411     PetscCall(PetscOptionsReal("-tao_crtol","Stop if relative constraint violations within","TaoSetConstraintTolerances",tao->crtol,&tao->crtol,&flg));
412     if (flg) tao->crtol_changed = PETSC_TRUE;
413     PetscCall(PetscOptionsReal("-tao_gatol","Stop if norm of gradient less than","TaoSetTolerances",tao->gatol,&tao->gatol,&flg));
414     if (flg) tao->gatol_changed = PETSC_TRUE;
415     PetscCall(PetscOptionsReal("-tao_grtol","Stop if norm of gradient divided by the function value is less than","TaoSetTolerances",tao->grtol,&tao->grtol,&flg));
416     if (flg) tao->grtol_changed = PETSC_TRUE;
417     PetscCall(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));
418     if (flg) tao->gttol_changed = PETSC_TRUE;
419     PetscCall(PetscOptionsInt("-tao_max_it","Stop if iteration number exceeds","TaoSetMaximumIterations",tao->max_it,&tao->max_it,&flg));
420     if (flg) tao->max_it_changed = PETSC_TRUE;
421     PetscCall(PetscOptionsInt("-tao_max_funcs","Stop if number of function evaluations exceeds","TaoSetMaximumFunctionEvaluations",tao->max_funcs,&tao->max_funcs,&flg));
422     if (flg) tao->max_funcs_changed = PETSC_TRUE;
423     PetscCall(PetscOptionsReal("-tao_fmin","Stop if function less than","TaoSetFunctionLowerBound",tao->fmin,&tao->fmin,&flg));
424     if (flg) tao->fmin_changed = PETSC_TRUE;
425     PetscCall(PetscOptionsReal("-tao_steptol","Stop if step size or trust region radius less than","",tao->steptol,&tao->steptol,&flg));
426     if (flg) tao->steptol_changed = PETSC_TRUE;
427     PetscCall(PetscOptionsReal("-tao_trust0","Initial trust region radius","TaoSetTrustRegionRadius",tao->trust0,&tao->trust0,&flg));
428     if (flg) tao->trust0_changed = PETSC_TRUE;
429     PetscCall(PetscOptionsString("-tao_view_solution","view solution vector after each evaluation","TaoSetMonitor","stdout",monfilename,sizeof(monfilename),&flg));
430     if (flg) {
431       PetscCall(PetscViewerASCIIOpen(comm,monfilename,&monviewer));
432       PetscCall(TaoSetMonitor(tao,TaoSolutionMonitor,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy));
433     }
434 
435     PetscCall(PetscOptionsBool("-tao_converged_reason","Print reason for TAO converged","TaoSolve",tao->printreason,&tao->printreason,NULL));
436     PetscCall(PetscOptionsString("-tao_view_gradient","view gradient vector after each evaluation","TaoSetMonitor","stdout",monfilename,sizeof(monfilename),&flg));
437     if (flg) {
438       PetscCall(PetscViewerASCIIOpen(comm,monfilename,&monviewer));
439       PetscCall(TaoSetMonitor(tao,TaoGradientMonitor,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy));
440     }
441 
442     PetscCall(PetscOptionsString("-tao_view_stepdirection","view step direction vector after each iteration","TaoSetMonitor","stdout",monfilename,sizeof(monfilename),&flg));
443     if (flg) {
444       PetscCall(PetscViewerASCIIOpen(comm,monfilename,&monviewer));
445       PetscCall(TaoSetMonitor(tao,TaoStepDirectionMonitor,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy));
446     }
447 
448     PetscCall(PetscOptionsString("-tao_view_residual","view least-squares residual vector after each evaluation","TaoSetMonitor","stdout",monfilename,sizeof(monfilename),&flg));
449     if (flg) {
450       PetscCall(PetscViewerASCIIOpen(comm,monfilename,&monviewer));
451       PetscCall(TaoSetMonitor(tao,TaoResidualMonitor,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy));
452     }
453 
454     PetscCall(PetscOptionsString("-tao_monitor","Use the default convergence monitor","TaoSetMonitor","stdout",monfilename,sizeof(monfilename),&flg));
455     if (flg) {
456       PetscCall(PetscViewerASCIIOpen(comm,monfilename,&monviewer));
457       PetscCall(TaoSetMonitor(tao,TaoMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy));
458     }
459 
460     PetscCall(PetscOptionsString("-tao_gmonitor","Use the convergence monitor with extra globalization info","TaoSetMonitor","stdout",monfilename,sizeof(monfilename),&flg));
461     if (flg) {
462       PetscCall(PetscViewerASCIIOpen(comm,monfilename,&monviewer));
463       PetscCall(TaoSetMonitor(tao,TaoDefaultGMonitor,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy));
464     }
465 
466     PetscCall(PetscOptionsString("-tao_smonitor","Use the short convergence monitor","TaoSetMonitor","stdout",monfilename,sizeof(monfilename),&flg));
467     if (flg) {
468       PetscCall(PetscViewerASCIIOpen(comm,monfilename,&monviewer));
469       PetscCall(TaoSetMonitor(tao,TaoDefaultSMonitor,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy));
470     }
471 
472     PetscCall(PetscOptionsString("-tao_cmonitor","Use the default convergence monitor with constraint norm","TaoSetMonitor","stdout",monfilename,sizeof(monfilename),&flg));
473     if (flg) {
474       PetscCall(PetscViewerASCIIOpen(comm,monfilename,&monviewer));
475       PetscCall(TaoSetMonitor(tao,TaoDefaultCMonitor,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy));
476     }
477 
478     flg = PETSC_FALSE;
479     PetscCall(PetscOptionsBool("-tao_cancelmonitors","cancel all monitors and call any registered destroy routines","TaoCancelMonitors",flg,&flg,NULL));
480     if (flg) PetscCall(TaoCancelMonitors(tao));
481 
482     flg = PETSC_FALSE;
483     PetscCall(PetscOptionsBool("-tao_draw_solution","Plot solution vector at each iteration","TaoSetMonitor",flg,&flg,NULL));
484     if (flg) {
485       TaoMonitorDrawCtx drawctx;
486       PetscInt          howoften = 1;
487       PetscCall(TaoMonitorDrawCtxCreate(PetscObjectComm((PetscObject)tao),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&drawctx));
488       PetscCall(TaoSetMonitor(tao,TaoDrawSolutionMonitor,drawctx,(PetscErrorCode (*)(void**))TaoMonitorDrawCtxDestroy));
489     }
490 
491     flg = PETSC_FALSE;
492     PetscCall(PetscOptionsBool("-tao_draw_step","plots step direction at each iteration","TaoSetMonitor",flg,&flg,NULL));
493     if (flg) {
494       PetscCall(TaoSetMonitor(tao,TaoDrawStepMonitor,NULL,NULL));
495     }
496 
497     flg = PETSC_FALSE;
498     PetscCall(PetscOptionsBool("-tao_draw_gradient","plots gradient at each iteration","TaoSetMonitor",flg,&flg,NULL));
499     if (flg) {
500       TaoMonitorDrawCtx drawctx;
501       PetscInt          howoften = 1;
502       PetscCall(TaoMonitorDrawCtxCreate(PetscObjectComm((PetscObject)tao),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&drawctx));
503       PetscCall(TaoSetMonitor(tao,TaoDrawGradientMonitor,drawctx,(PetscErrorCode (*)(void**))TaoMonitorDrawCtxDestroy));
504     }
505     flg = PETSC_FALSE;
506     PetscCall(PetscOptionsBool("-tao_fd_gradient","compute gradient using finite differences","TaoDefaultComputeGradient",flg,&flg,NULL));
507     if (flg) {
508       PetscCall(TaoSetGradient(tao,NULL,TaoDefaultComputeGradient,NULL));
509     }
510     flg = PETSC_FALSE;
511     PetscCall(PetscOptionsBool("-tao_fd_hessian","compute hessian using finite differences","TaoDefaultComputeHessian",flg,&flg,NULL));
512     if (flg) {
513       Mat H;
514 
515       PetscCall(MatCreate(PetscObjectComm((PetscObject)tao),&H));
516       PetscCall(MatSetType(H,MATAIJ));
517       PetscCall(TaoSetHessian(tao,H,H,TaoDefaultComputeHessian,NULL));
518       PetscCall(MatDestroy(&H));
519     }
520     flg = PETSC_FALSE;
521     PetscCall(PetscOptionsBool("-tao_mf_hessian","compute matrix-free hessian using finite differences","TaoDefaultComputeHessianMFFD",flg,&flg,NULL));
522     if (flg) {
523       Mat H;
524 
525       PetscCall(MatCreate(PetscObjectComm((PetscObject)tao),&H));
526       PetscCall(TaoSetHessian(tao,H,H,TaoDefaultComputeHessianMFFD,NULL));
527       PetscCall(MatDestroy(&H));
528     }
529     flg = PETSC_FALSE;
530     PetscCall(PetscOptionsBool("-tao_recycle_history","enable recycling/re-using information from the previous TaoSolve() call for some algorithms","TaoSetRecycleHistory",flg,&flg,NULL));
531     if (flg) {
532       PetscCall(TaoSetRecycleHistory(tao,PETSC_TRUE));
533     }
534     PetscCall(PetscOptionsEnum("-tao_subset_type","subset type","",TaoSubSetTypes,(PetscEnum)tao->subset_type,(PetscEnum*)&tao->subset_type,NULL));
535 
536     if (tao->ksp) {
537       PetscCall(PetscOptionsBool("-tao_ksp_ew","Use Eisentat-Walker linear system convergence test","TaoKSPSetUseEW",tao->ksp_ewconv,&tao->ksp_ewconv,NULL));
538       PetscCall(TaoKSPSetUseEW(tao,tao->ksp_ewconv));
539     }
540 
541     if (tao->linesearch) {
542       PetscCall(TaoLineSearchSetFromOptions(tao->linesearch));
543     }
544 
545     if (tao->ops->setfromoptions) {
546       PetscCall((*tao->ops->setfromoptions)(PetscOptionsObject,tao));
547     }
548   }
549   PetscOptionsEnd();
550   PetscFunctionReturn(0);
551 }
552 
553 /*@C
554    TaoViewFromOptions - View from Options
555 
556    Collective on Tao
557 
558    Input Parameters:
559 +  A - the  Tao context
560 .  obj - Optional object
561 -  name - command line option
562 
563    Level: intermediate
564 .seealso: `Tao`, `TaoView`, `PetscObjectViewFromOptions()`, `TaoCreate()`
565 @*/
566 PetscErrorCode  TaoViewFromOptions(Tao A,PetscObject obj,const char name[])
567 {
568   PetscFunctionBegin;
569   PetscValidHeaderSpecific(A,TAO_CLASSID,1);
570   PetscCall(PetscObjectViewFromOptions((PetscObject)A,obj,name));
571   PetscFunctionReturn(0);
572 }
573 
574 /*@C
575   TaoView - Prints information about the Tao
576 
577   Collective on Tao
578 
579   InputParameters:
580 + tao - the Tao context
581 - viewer - visualization context
582 
583   Options Database Key:
584 . -tao_view - Calls TaoView() at the end of TaoSolve()
585 
586   Notes:
587   The available visualization contexts include
588 +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
589 -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
590          output where only the first processor opens
591          the file.  All other processors send their
592          data to the first processor to print.
593 
594   Level: beginner
595 
596 .seealso: `PetscViewerASCIIOpen()`
597 @*/
598 PetscErrorCode TaoView(Tao tao, PetscViewer viewer)
599 {
600   PetscBool           isascii,isstring;
601   TaoType             type;
602 
603   PetscFunctionBegin;
604   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
605   if (!viewer) {
606     PetscCall(PetscViewerASCIIGetStdout(((PetscObject)tao)->comm,&viewer));
607   }
608   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
609   PetscCheckSameComm(tao,1,viewer,2);
610 
611   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii));
612   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring));
613   if (isascii) {
614     PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)tao,viewer));
615 
616     if (tao->ops->view) {
617       PetscCall(PetscViewerASCIIPushTab(viewer));
618       PetscCall((*tao->ops->view)(tao,viewer));
619       PetscCall(PetscViewerASCIIPopTab(viewer));
620     }
621     if (tao->linesearch) {
622       PetscCall(PetscViewerASCIIPushTab(viewer));
623       PetscCall(TaoLineSearchView(tao->linesearch,viewer));
624       PetscCall(PetscViewerASCIIPopTab(viewer));
625     }
626     if (tao->ksp) {
627       PetscCall(PetscViewerASCIIPushTab(viewer));
628       PetscCall(KSPView(tao->ksp,viewer));
629       PetscCall(PetscViewerASCIIPrintf(viewer,"total KSP iterations: %" PetscInt_FMT "\n",tao->ksp_tot_its));
630       PetscCall(PetscViewerASCIIPopTab(viewer));
631     }
632 
633     PetscCall(PetscViewerASCIIPushTab(viewer));
634 
635     if (tao->XL || tao->XU) {
636       PetscCall(PetscViewerASCIIPrintf(viewer,"Active Set subset type: %s\n",TaoSubSetTypes[tao->subset_type]));
637     }
638 
639     PetscCall(PetscViewerASCIIPrintf(viewer,"convergence tolerances: gatol=%g,",(double)tao->gatol));
640     PetscCall(PetscViewerASCIIPrintf(viewer," steptol=%g,",(double)tao->steptol));
641     PetscCall(PetscViewerASCIIPrintf(viewer," gttol=%g\n",(double)tao->gttol));
642     PetscCall(PetscViewerASCIIPrintf(viewer,"Residual in Function/Gradient:=%g\n",(double)tao->residual));
643 
644     if (tao->constrained) {
645       PetscCall(PetscViewerASCIIPrintf(viewer,"convergence tolerances:"));
646       PetscCall(PetscViewerASCIIPrintf(viewer," catol=%g,",(double)tao->catol));
647       PetscCall(PetscViewerASCIIPrintf(viewer," crtol=%g\n",(double)tao->crtol));
648       PetscCall(PetscViewerASCIIPrintf(viewer,"Residual in Constraints:=%g\n",(double)tao->cnorm));
649     }
650 
651     if (tao->trust < tao->steptol) {
652       PetscCall(PetscViewerASCIIPrintf(viewer,"convergence tolerances: steptol=%g\n",(double)tao->steptol));
653       PetscCall(PetscViewerASCIIPrintf(viewer,"Final trust region radius:=%g\n",(double)tao->trust));
654     }
655 
656     if (tao->fmin>-1.e25) {
657       PetscCall(PetscViewerASCIIPrintf(viewer,"convergence tolerances: function minimum=%g\n",(double)tao->fmin));
658     }
659     PetscCall(PetscViewerASCIIPrintf(viewer,"Objective value=%g\n",(double)tao->fc));
660 
661     PetscCall(PetscViewerASCIIPrintf(viewer,"total number of iterations=%" PetscInt_FMT ",          ",tao->niter));
662     PetscCall(PetscViewerASCIIPrintf(viewer,"              (max: %" PetscInt_FMT ")\n",tao->max_it));
663 
664     if (tao->nfuncs>0) {
665       PetscCall(PetscViewerASCIIPrintf(viewer,"total number of function evaluations=%" PetscInt_FMT ",",tao->nfuncs));
666       PetscCall(PetscViewerASCIIPrintf(viewer,"                max: %" PetscInt_FMT "\n",tao->max_funcs));
667     }
668     if (tao->ngrads>0) {
669       PetscCall(PetscViewerASCIIPrintf(viewer,"total number of gradient evaluations=%" PetscInt_FMT ",",tao->ngrads));
670       PetscCall(PetscViewerASCIIPrintf(viewer,"                max: %" PetscInt_FMT "\n",tao->max_funcs));
671     }
672     if (tao->nfuncgrads>0) {
673       PetscCall(PetscViewerASCIIPrintf(viewer,"total number of function/gradient evaluations=%" PetscInt_FMT ",",tao->nfuncgrads));
674       PetscCall(PetscViewerASCIIPrintf(viewer,"    (max: %" PetscInt_FMT ")\n",tao->max_funcs));
675     }
676     if (tao->nhess>0) {
677       PetscCall(PetscViewerASCIIPrintf(viewer,"total number of Hessian evaluations=%" PetscInt_FMT "\n",tao->nhess));
678     }
679     if (tao->nconstraints>0) {
680       PetscCall(PetscViewerASCIIPrintf(viewer,"total number of constraint function evaluations=%" PetscInt_FMT "\n",tao->nconstraints));
681     }
682     if (tao->njac>0) {
683       PetscCall(PetscViewerASCIIPrintf(viewer,"total number of Jacobian evaluations=%" PetscInt_FMT "\n",tao->njac));
684     }
685 
686     if (tao->reason>0) {
687       PetscCall(PetscViewerASCIIPrintf(viewer,    "Solution converged: "));
688       switch (tao->reason) {
689       case TAO_CONVERGED_GATOL:
690         PetscCall(PetscViewerASCIIPrintf(viewer," ||g(X)|| <= gatol\n"));
691         break;
692       case TAO_CONVERGED_GRTOL:
693         PetscCall(PetscViewerASCIIPrintf(viewer," ||g(X)||/|f(X)| <= grtol\n"));
694         break;
695       case TAO_CONVERGED_GTTOL:
696         PetscCall(PetscViewerASCIIPrintf(viewer," ||g(X)||/||g(X0)|| <= gttol\n"));
697         break;
698       case TAO_CONVERGED_STEPTOL:
699         PetscCall(PetscViewerASCIIPrintf(viewer," Steptol -- step size small\n"));
700         break;
701       case TAO_CONVERGED_MINF:
702         PetscCall(PetscViewerASCIIPrintf(viewer," Minf --  f < fmin\n"));
703         break;
704       case TAO_CONVERGED_USER:
705         PetscCall(PetscViewerASCIIPrintf(viewer," User Terminated\n"));
706         break;
707       default:
708         PetscCall(PetscViewerASCIIPrintf(viewer,"\n"));
709         break;
710       }
711     } else {
712       PetscCall(PetscViewerASCIIPrintf(viewer,"Solver terminated: %d",tao->reason));
713       switch (tao->reason) {
714       case TAO_DIVERGED_MAXITS:
715         PetscCall(PetscViewerASCIIPrintf(viewer," Maximum Iterations\n"));
716         break;
717       case TAO_DIVERGED_NAN:
718         PetscCall(PetscViewerASCIIPrintf(viewer," NAN or Inf encountered\n"));
719         break;
720       case TAO_DIVERGED_MAXFCN:
721         PetscCall(PetscViewerASCIIPrintf(viewer," Maximum Function Evaluations\n"));
722         break;
723       case TAO_DIVERGED_LS_FAILURE:
724         PetscCall(PetscViewerASCIIPrintf(viewer," Line Search Failure\n"));
725         break;
726       case TAO_DIVERGED_TR_REDUCTION:
727         PetscCall(PetscViewerASCIIPrintf(viewer," Trust Region too small\n"));
728         break;
729       case TAO_DIVERGED_USER:
730         PetscCall(PetscViewerASCIIPrintf(viewer," User Terminated\n"));
731         break;
732       default:
733         PetscCall(PetscViewerASCIIPrintf(viewer,"\n"));
734         break;
735       }
736     }
737     PetscCall(PetscViewerASCIIPopTab(viewer));
738   } else if (isstring) {
739     PetscCall(TaoGetType(tao,&type));
740     PetscCall(PetscViewerStringSPrintf(viewer," %-3.3s",type));
741   }
742   PetscFunctionReturn(0);
743 }
744 
745 /*@
746   TaoSetRecycleHistory - Sets the boolean flag to enable/disable re-using
747   iterate information from the previous TaoSolve(). This feature is disabled by
748   default.
749 
750   For conjugate gradient methods (BNCG), this re-uses the latest search direction
751   from the previous TaoSolve() call when computing the first search direction in a
752   new solution. By default, CG methods set the first search direction to the
753   negative gradient.
754 
755   For quasi-Newton family of methods (BQNLS, BQNKLS, BQNKTR, BQNKTL), this re-uses
756   the accumulated quasi-Newton Hessian approximation from the previous TaoSolve()
757   call. By default, QN family of methods reset the initial Hessian approximation to
758   the identity matrix.
759 
760   For any other algorithm, this setting has no effect.
761 
762   Logically collective on Tao
763 
764   Input Parameters:
765 + tao - the Tao context
766 - recycle - boolean flag
767 
768   Options Database Keys:
769 . -tao_recycle_history <true,false> - reuse the history
770 
771   Level: intermediate
772 
773 .seealso: `TaoSetRecycleHistory()`, `TAOBNCG`, `TAOBQNLS`, `TAOBQNKLS`, `TAOBQNKTR`, `TAOBQNKTL`
774 
775 @*/
776 PetscErrorCode TaoSetRecycleHistory(Tao tao, PetscBool recycle)
777 {
778   PetscFunctionBegin;
779   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
780   PetscValidLogicalCollectiveBool(tao,recycle,2);
781   tao->recycle = recycle;
782   PetscFunctionReturn(0);
783 }
784 
785 /*@
786   TaoGetRecycleHistory - Retrieve the boolean flag for re-using iterate information
787   from the previous TaoSolve(). This feature is disabled by default.
788 
789   Logically collective on Tao
790 
791   Input Parameters:
792 . tao - the Tao context
793 
794   Output Parameters:
795 . recycle - boolean flag
796 
797   Level: intermediate
798 
799 .seealso: `TaoGetRecycleHistory()`, `TAOBNCG`, `TAOBQNLS`, `TAOBQNKLS`, `TAOBQNKTR`, `TAOBQNKTL`
800 
801 @*/
802 PetscErrorCode TaoGetRecycleHistory(Tao tao, PetscBool *recycle)
803 {
804   PetscFunctionBegin;
805   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
806   PetscValidBoolPointer(recycle,2);
807   *recycle = tao->recycle;
808   PetscFunctionReturn(0);
809 }
810 
811 /*@
812   TaoSetTolerances - Sets parameters used in TAO convergence tests
813 
814   Logically collective on Tao
815 
816   Input Parameters:
817 + tao - the Tao context
818 . gatol - stop if norm of gradient is less than this
819 . grtol - stop if relative norm of gradient is less than this
820 - gttol - stop if norm of gradient is reduced by this factor
821 
822   Options Database Keys:
823 + -tao_gatol <gatol> - Sets gatol
824 . -tao_grtol <grtol> - Sets grtol
825 - -tao_gttol <gttol> - Sets gttol
826 
827   Stopping Criteria:
828 $ ||g(X)||                            <= gatol
829 $ ||g(X)|| / |f(X)|                   <= grtol
830 $ ||g(X)|| / ||g(X0)||                <= gttol
831 
832   Notes:
833   Use PETSC_DEFAULT to leave one or more tolerances unchanged.
834 
835   Level: beginner
836 
837 .seealso: `TaoGetTolerances()`
838 
839 @*/
840 PetscErrorCode TaoSetTolerances(Tao tao, PetscReal gatol, PetscReal grtol, PetscReal gttol)
841 {
842   PetscFunctionBegin;
843   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
844   PetscValidLogicalCollectiveReal(tao,gatol,2);
845   PetscValidLogicalCollectiveReal(tao,grtol,3);
846   PetscValidLogicalCollectiveReal(tao,gttol,4);
847 
848   if (gatol != PETSC_DEFAULT) {
849     if (gatol<0) {
850       PetscCall(PetscInfo(tao,"Tried to set negative gatol -- ignored.\n"));
851     } else {
852       tao->gatol = PetscMax(0,gatol);
853       tao->gatol_changed = PETSC_TRUE;
854     }
855   }
856 
857   if (grtol != PETSC_DEFAULT) {
858     if (grtol<0) {
859       PetscCall(PetscInfo(tao,"Tried to set negative grtol -- ignored.\n"));
860     } else {
861       tao->grtol = PetscMax(0,grtol);
862       tao->grtol_changed = PETSC_TRUE;
863     }
864   }
865 
866   if (gttol != PETSC_DEFAULT) {
867     if (gttol<0) {
868       PetscCall(PetscInfo(tao,"Tried to set negative gttol -- ignored.\n"));
869     } else {
870       tao->gttol = PetscMax(0,gttol);
871       tao->gttol_changed = PETSC_TRUE;
872     }
873   }
874   PetscFunctionReturn(0);
875 }
876 
877 /*@
878   TaoSetConstraintTolerances - Sets constraint tolerance parameters used in TAO  convergence tests
879 
880   Logically collective on Tao
881 
882   Input Parameters:
883 + tao - the Tao context
884 . catol - absolute constraint tolerance, constraint norm must be less than catol for used for gatol convergence criteria
885 - crtol - relative constraint tolerance, constraint norm must be less than crtol for used for gatol, gttol convergence criteria
886 
887   Options Database Keys:
888 + -tao_catol <catol> - Sets catol
889 - -tao_crtol <crtol> - Sets crtol
890 
891   Notes:
892   Use PETSC_DEFAULT to leave any tolerance unchanged.
893 
894   Level: intermediate
895 
896 .seealso: `TaoGetTolerances()`, `TaoGetConstraintTolerances()`, `TaoSetTolerances()`
897 
898 @*/
899 PetscErrorCode TaoSetConstraintTolerances(Tao tao, PetscReal catol, PetscReal crtol)
900 {
901   PetscFunctionBegin;
902   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
903   PetscValidLogicalCollectiveReal(tao,catol,2);
904   PetscValidLogicalCollectiveReal(tao,crtol,3);
905 
906   if (catol != PETSC_DEFAULT) {
907     if (catol<0) {
908       PetscCall(PetscInfo(tao,"Tried to set negative catol -- ignored.\n"));
909     } else {
910       tao->catol = PetscMax(0,catol);
911       tao->catol_changed = PETSC_TRUE;
912     }
913   }
914 
915   if (crtol != PETSC_DEFAULT) {
916     if (crtol<0) {
917       PetscCall(PetscInfo(tao,"Tried to set negative crtol -- ignored.\n"));
918     } else {
919       tao->crtol = PetscMax(0,crtol);
920       tao->crtol_changed = PETSC_TRUE;
921     }
922   }
923   PetscFunctionReturn(0);
924 }
925 
926 /*@
927   TaoGetConstraintTolerances - Gets constraint tolerance parameters used in TAO  convergence tests
928 
929   Not ollective
930 
931   Input Parameter:
932 . tao - the Tao context
933 
934   Output Parameters:
935 + catol - absolute constraint tolerance, constraint norm must be less than catol for used for gatol convergence criteria
936 - crtol - relative constraint tolerance, constraint norm must be less than crtol for used for gatol, gttol convergence criteria
937 
938   Level: intermediate
939 
940 .seealso: `TaoGetTolerances()`, `TaoSetTolerances()`, `TaoSetConstraintTolerances()`
941 
942 @*/
943 PetscErrorCode TaoGetConstraintTolerances(Tao tao, PetscReal *catol, PetscReal *crtol)
944 {
945   PetscFunctionBegin;
946   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
947   if (catol) *catol = tao->catol;
948   if (crtol) *crtol = tao->crtol;
949   PetscFunctionReturn(0);
950 }
951 
952 /*@
953    TaoSetFunctionLowerBound - Sets a bound on the solution objective value.
954    When an approximate solution with an objective value below this number
955    has been found, the solver will terminate.
956 
957    Logically Collective on Tao
958 
959    Input Parameters:
960 +  tao - the Tao solver context
961 -  fmin - the tolerance
962 
963    Options Database Keys:
964 .    -tao_fmin <fmin> - sets the minimum function value
965 
966    Level: intermediate
967 
968 .seealso: `TaoSetTolerances()`
969 @*/
970 PetscErrorCode TaoSetFunctionLowerBound(Tao tao,PetscReal fmin)
971 {
972   PetscFunctionBegin;
973   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
974   PetscValidLogicalCollectiveReal(tao,fmin,2);
975   tao->fmin = fmin;
976   tao->fmin_changed = PETSC_TRUE;
977   PetscFunctionReturn(0);
978 }
979 
980 /*@
981    TaoGetFunctionLowerBound - Gets the bound on the solution objective value.
982    When an approximate solution with an objective value below this number
983    has been found, the solver will terminate.
984 
985    Not collective on Tao
986 
987    Input Parameters:
988 .  tao - the Tao solver context
989 
990    OutputParameters:
991 .  fmin - the minimum function value
992 
993    Level: intermediate
994 
995 .seealso: `TaoSetFunctionLowerBound()`
996 @*/
997 PetscErrorCode TaoGetFunctionLowerBound(Tao tao,PetscReal *fmin)
998 {
999   PetscFunctionBegin;
1000   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
1001   PetscValidRealPointer(fmin,2);
1002   *fmin = tao->fmin;
1003   PetscFunctionReturn(0);
1004 }
1005 
1006 /*@
1007    TaoSetMaximumFunctionEvaluations - Sets a maximum number of
1008    function evaluations.
1009 
1010    Logically Collective on Tao
1011 
1012    Input Parameters:
1013 +  tao - the Tao solver context
1014 -  nfcn - the maximum number of function evaluations (>=0)
1015 
1016    Options Database Keys:
1017 .    -tao_max_funcs <nfcn> - sets the maximum number of function evaluations
1018 
1019    Level: intermediate
1020 
1021 .seealso: `TaoSetTolerances()`, `TaoSetMaximumIterations()`
1022 @*/
1023 
1024 PetscErrorCode TaoSetMaximumFunctionEvaluations(Tao tao,PetscInt nfcn)
1025 {
1026   PetscFunctionBegin;
1027   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
1028   PetscValidLogicalCollectiveInt(tao,nfcn,2);
1029   if (nfcn >= 0) { tao->max_funcs = PetscMax(0,nfcn); }
1030   else { tao->max_funcs = -1; }
1031   tao->max_funcs_changed = PETSC_TRUE;
1032   PetscFunctionReturn(0);
1033 }
1034 
1035 /*@
1036    TaoGetMaximumFunctionEvaluations - Sets a maximum number of
1037    function evaluations.
1038 
1039    Not Collective
1040 
1041    Input Parameters:
1042 .  tao - the Tao solver context
1043 
1044    Output Parameters:
1045 .  nfcn - the maximum number of function evaluations
1046 
1047    Level: intermediate
1048 
1049 .seealso: `TaoSetMaximumFunctionEvaluations()`, `TaoGetMaximumIterations()`
1050 @*/
1051 
1052 PetscErrorCode TaoGetMaximumFunctionEvaluations(Tao tao,PetscInt *nfcn)
1053 {
1054   PetscFunctionBegin;
1055   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
1056   PetscValidIntPointer(nfcn,2);
1057   *nfcn = tao->max_funcs;
1058   PetscFunctionReturn(0);
1059 }
1060 
1061 /*@
1062    TaoGetCurrentFunctionEvaluations - Get current number of
1063    function evaluations.
1064 
1065    Not Collective
1066 
1067    Input Parameters:
1068 .  tao - the Tao solver context
1069 
1070    Output Parameters:
1071 .  nfuncs - the current number of function evaluations (maximum between gradient and function evaluations)
1072 
1073    Level: intermediate
1074 
1075 .seealso: `TaoSetMaximumFunctionEvaluations()`, `TaoGetMaximumFunctionEvaluations()`, `TaoGetMaximumIterations()`
1076 @*/
1077 
1078 PetscErrorCode TaoGetCurrentFunctionEvaluations(Tao tao,PetscInt *nfuncs)
1079 {
1080   PetscFunctionBegin;
1081   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
1082   PetscValidIntPointer(nfuncs,2);
1083   *nfuncs = PetscMax(tao->nfuncs,tao->nfuncgrads);
1084   PetscFunctionReturn(0);
1085 }
1086 
1087 /*@
1088    TaoSetMaximumIterations - Sets a maximum number of iterates.
1089 
1090    Logically Collective on Tao
1091 
1092    Input Parameters:
1093 +  tao - the Tao solver context
1094 -  maxits - the maximum number of iterates (>=0)
1095 
1096    Options Database Keys:
1097 .    -tao_max_it <its> - sets the maximum number of iterations
1098 
1099    Level: intermediate
1100 
1101 .seealso: `TaoSetTolerances()`, `TaoSetMaximumFunctionEvaluations()`
1102 @*/
1103 PetscErrorCode TaoSetMaximumIterations(Tao tao,PetscInt maxits)
1104 {
1105   PetscFunctionBegin;
1106   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
1107   PetscValidLogicalCollectiveInt(tao,maxits,2);
1108   tao->max_it = PetscMax(0,maxits);
1109   tao->max_it_changed = PETSC_TRUE;
1110   PetscFunctionReturn(0);
1111 }
1112 
1113 /*@
1114    TaoGetMaximumIterations - Sets a maximum number of iterates.
1115 
1116    Not Collective
1117 
1118    Input Parameters:
1119 .  tao - the Tao solver context
1120 
1121    Output Parameters:
1122 .  maxits - the maximum number of iterates
1123 
1124    Level: intermediate
1125 
1126 .seealso: `TaoSetMaximumIterations()`, `TaoGetMaximumFunctionEvaluations()`
1127 @*/
1128 PetscErrorCode TaoGetMaximumIterations(Tao tao,PetscInt *maxits)
1129 {
1130   PetscFunctionBegin;
1131   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
1132   PetscValidIntPointer(maxits,2);
1133   *maxits = tao->max_it;
1134   PetscFunctionReturn(0);
1135 }
1136 
1137 /*@
1138    TaoSetInitialTrustRegionRadius - Sets the initial trust region radius.
1139 
1140    Logically collective on Tao
1141 
1142    Input Parameters:
1143 +  tao - a TAO optimization solver
1144 -  radius - the trust region radius
1145 
1146    Level: intermediate
1147 
1148    Options Database Key:
1149 .  -tao_trust0 <t0> - sets initial trust region radius
1150 
1151 .seealso: `TaoGetTrustRegionRadius()`, `TaoSetTrustRegionTolerance()`
1152 @*/
1153 PetscErrorCode TaoSetInitialTrustRegionRadius(Tao tao, PetscReal radius)
1154 {
1155   PetscFunctionBegin;
1156   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
1157   PetscValidLogicalCollectiveReal(tao,radius,2);
1158   tao->trust0 = PetscMax(0.0,radius);
1159   tao->trust0_changed = PETSC_TRUE;
1160   PetscFunctionReturn(0);
1161 }
1162 
1163 /*@
1164    TaoGetInitialTrustRegionRadius - Sets the initial trust region radius.
1165 
1166    Not Collective
1167 
1168    Input Parameter:
1169 .  tao - a TAO optimization solver
1170 
1171    Output Parameter:
1172 .  radius - the trust region radius
1173 
1174    Level: intermediate
1175 
1176 .seealso: `TaoSetInitialTrustRegionRadius()`, `TaoGetCurrentTrustRegionRadius()`
1177 @*/
1178 PetscErrorCode TaoGetInitialTrustRegionRadius(Tao tao, PetscReal *radius)
1179 {
1180   PetscFunctionBegin;
1181   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
1182   PetscValidRealPointer(radius,2);
1183   *radius = tao->trust0;
1184   PetscFunctionReturn(0);
1185 }
1186 
1187 /*@
1188    TaoGetCurrentTrustRegionRadius - Gets the current trust region radius.
1189 
1190    Not Collective
1191 
1192    Input Parameter:
1193 .  tao - a TAO optimization solver
1194 
1195    Output Parameter:
1196 .  radius - the trust region radius
1197 
1198    Level: intermediate
1199 
1200 .seealso: `TaoSetInitialTrustRegionRadius()`, `TaoGetInitialTrustRegionRadius()`
1201 @*/
1202 PetscErrorCode TaoGetCurrentTrustRegionRadius(Tao tao, PetscReal *radius)
1203 {
1204   PetscFunctionBegin;
1205   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
1206   PetscValidRealPointer(radius,2);
1207   *radius = tao->trust;
1208   PetscFunctionReturn(0);
1209 }
1210 
1211 /*@
1212   TaoGetTolerances - gets the current values of tolerances
1213 
1214   Not Collective
1215 
1216   Input Parameter:
1217 . tao - the Tao context
1218 
1219   Output Parameters:
1220 + gatol - stop if norm of gradient is less than this
1221 . grtol - stop if relative norm of gradient is less than this
1222 - gttol - stop if norm of gradient is reduced by a this factor
1223 
1224   Note: NULL can be used as an argument if not all tolerances values are needed
1225 
1226 .seealso `TaoSetTolerances()`
1227 
1228   Level: intermediate
1229 @*/
1230 PetscErrorCode TaoGetTolerances(Tao tao, PetscReal *gatol, PetscReal *grtol, PetscReal *gttol)
1231 {
1232   PetscFunctionBegin;
1233   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
1234   if (gatol) *gatol = tao->gatol;
1235   if (grtol) *grtol = tao->grtol;
1236   if (gttol) *gttol = tao->gttol;
1237   PetscFunctionReturn(0);
1238 }
1239 
1240 /*@
1241   TaoGetKSP - Gets the linear solver used by the optimization solver.
1242   Application writers should use TaoGetKSP if they need direct access
1243   to the PETSc KSP object.
1244 
1245   Not Collective
1246 
1247    Input Parameters:
1248 .  tao - the TAO solver
1249 
1250    Output Parameters:
1251 .  ksp - the KSP linear solver used in the optimization solver
1252 
1253    Level: intermediate
1254 
1255 @*/
1256 PetscErrorCode TaoGetKSP(Tao tao, KSP *ksp)
1257 {
1258   PetscFunctionBegin;
1259   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
1260   PetscValidPointer(ksp,2);
1261   *ksp = tao->ksp;
1262   PetscFunctionReturn(0);
1263 }
1264 
1265 /*@
1266    TaoGetLinearSolveIterations - Gets the total number of linear iterations
1267    used by the TAO solver
1268 
1269    Not Collective
1270 
1271    Input Parameter:
1272 .  tao - TAO context
1273 
1274    Output Parameter:
1275 .  lits - number of linear iterations
1276 
1277    Notes:
1278    This counter is reset to zero for each successive call to TaoSolve()
1279 
1280    Level: intermediate
1281 
1282 .seealso: `TaoGetKSP()`
1283 @*/
1284 PetscErrorCode TaoGetLinearSolveIterations(Tao tao, PetscInt *lits)
1285 {
1286   PetscFunctionBegin;
1287   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
1288   PetscValidIntPointer(lits,2);
1289   *lits = tao->ksp_tot_its;
1290   PetscFunctionReturn(0);
1291 }
1292 
1293 /*@
1294   TaoGetLineSearch - Gets the line search used by the optimization solver.
1295   Application writers should use TaoGetLineSearch if they need direct access
1296   to the TaoLineSearch object.
1297 
1298   Not Collective
1299 
1300    Input Parameters:
1301 .  tao - the TAO solver
1302 
1303    Output Parameters:
1304 .  ls - the line search used in the optimization solver
1305 
1306    Level: intermediate
1307 
1308 @*/
1309 PetscErrorCode TaoGetLineSearch(Tao tao, TaoLineSearch *ls)
1310 {
1311   PetscFunctionBegin;
1312   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
1313   PetscValidPointer(ls,2);
1314   *ls = tao->linesearch;
1315   PetscFunctionReturn(0);
1316 }
1317 
1318 /*@
1319   TaoAddLineSearchCounts - Adds the number of function evaluations spent
1320   in the line search to the running total.
1321 
1322    Input Parameters:
1323 +  tao - the TAO solver
1324 -  ls - the line search used in the optimization solver
1325 
1326    Level: developer
1327 
1328 .seealso: `TaoLineSearchApply()`
1329 @*/
1330 PetscErrorCode TaoAddLineSearchCounts(Tao tao)
1331 {
1332   PetscBool      flg;
1333   PetscInt       nfeval,ngeval,nfgeval;
1334 
1335   PetscFunctionBegin;
1336   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
1337   if (tao->linesearch) {
1338     PetscCall(TaoLineSearchIsUsingTaoRoutines(tao->linesearch,&flg));
1339     if (!flg) {
1340       PetscCall(TaoLineSearchGetNumberFunctionEvaluations(tao->linesearch,&nfeval,&ngeval,&nfgeval));
1341       tao->nfuncs += nfeval;
1342       tao->ngrads += ngeval;
1343       tao->nfuncgrads += nfgeval;
1344     }
1345   }
1346   PetscFunctionReturn(0);
1347 }
1348 
1349 /*@
1350   TaoGetSolution - Returns the vector with the current TAO solution
1351 
1352   Not Collective
1353 
1354   Input Parameter:
1355 . tao - the Tao context
1356 
1357   Output Parameter:
1358 . X - the current solution
1359 
1360   Level: intermediate
1361 
1362   Note:  The returned vector will be the same object that was passed into TaoSetSolution()
1363 @*/
1364 PetscErrorCode TaoGetSolution(Tao tao, Vec *X)
1365 {
1366   PetscFunctionBegin;
1367   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
1368   PetscValidPointer(X,2);
1369   *X = tao->solution;
1370   PetscFunctionReturn(0);
1371 }
1372 
1373 /*@
1374    TaoResetStatistics - Initialize the statistics used by TAO for all of the solvers.
1375    These statistics include the iteration number, residual norms, and convergence status.
1376    This routine gets called before solving each optimization problem.
1377 
1378    Collective on Tao
1379 
1380    Input Parameters:
1381 .  solver - the Tao context
1382 
1383    Level: developer
1384 
1385 .seealso: `TaoCreate()`, `TaoSolve()`
1386 @*/
1387 PetscErrorCode TaoResetStatistics(Tao tao)
1388 {
1389   PetscFunctionBegin;
1390   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
1391   tao->niter        = 0;
1392   tao->nfuncs       = 0;
1393   tao->nfuncgrads   = 0;
1394   tao->ngrads       = 0;
1395   tao->nhess        = 0;
1396   tao->njac         = 0;
1397   tao->nconstraints = 0;
1398   tao->ksp_its      = 0;
1399   tao->ksp_tot_its  = 0;
1400   tao->reason       = TAO_CONTINUE_ITERATING;
1401   tao->residual     = 0.0;
1402   tao->cnorm        = 0.0;
1403   tao->step         = 0.0;
1404   tao->lsflag       = PETSC_FALSE;
1405   if (tao->hist_reset) tao->hist_len = 0;
1406   PetscFunctionReturn(0);
1407 }
1408 
1409 /*@C
1410   TaoSetUpdate - Sets the general-purpose update function called
1411   at the beginning of every iteration of the nonlinear solve. Specifically
1412   it is called at the top of every iteration, after the new solution and the gradient
1413   is determined, but before the Hessian is computed (if applicable).
1414 
1415   Logically Collective on Tao
1416 
1417   Input Parameters:
1418 + tao - The tao solver context
1419 - func - The function
1420 
1421   Calling sequence of func:
1422 $ func (Tao tao, PetscInt step);
1423 
1424 . step - The current step of the iteration
1425 
1426   Level: advanced
1427 
1428 .seealso `TaoSolve()`
1429 @*/
1430 PetscErrorCode TaoSetUpdate(Tao tao, PetscErrorCode (*func)(Tao, PetscInt, void*), void *ctx)
1431 {
1432   PetscFunctionBegin;
1433   PetscValidHeaderSpecific(tao, TAO_CLASSID,1);
1434   tao->ops->update = func;
1435   tao->user_update = ctx;
1436   PetscFunctionReturn(0);
1437 }
1438 
1439 /*@C
1440   TaoSetConvergenceTest - Sets the function that is to be used to test
1441   for convergence o fthe iterative minimization solution.  The new convergence
1442   testing routine will replace TAO's default convergence test.
1443 
1444   Logically Collective on Tao
1445 
1446   Input Parameters:
1447 + tao - the Tao object
1448 . conv - the routine to test for convergence
1449 - ctx - [optional] context for private data for the convergence routine
1450         (may be NULL)
1451 
1452   Calling sequence of conv:
1453 $   PetscErrorCode conv(Tao tao, void *ctx)
1454 
1455 + tao - the Tao object
1456 - ctx - [optional] convergence context
1457 
1458   Note: The new convergence testing routine should call TaoSetConvergedReason().
1459 
1460   Level: advanced
1461 
1462 .seealso: `TaoSetConvergedReason()`, `TaoGetSolutionStatus()`, `TaoGetTolerances()`, `TaoSetMonitor`
1463 
1464 @*/
1465 PetscErrorCode TaoSetConvergenceTest(Tao tao, PetscErrorCode (*conv)(Tao, void*), void *ctx)
1466 {
1467   PetscFunctionBegin;
1468   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
1469   tao->ops->convergencetest = conv;
1470   tao->cnvP = ctx;
1471   PetscFunctionReturn(0);
1472 }
1473 
1474 /*@C
1475    TaoSetMonitor - Sets an ADDITIONAL function that is to be used at every
1476    iteration of the solver to display the iteration's
1477    progress.
1478 
1479    Logically Collective on Tao
1480 
1481    Input Parameters:
1482 +  tao - the Tao solver context
1483 .  mymonitor - monitoring routine
1484 -  mctx - [optional] user-defined context for private data for the
1485           monitor routine (may be NULL)
1486 
1487    Calling sequence of mymonitor:
1488 .vb
1489      PetscErrorCode mymonitor(Tao tao,void *mctx)
1490 .ve
1491 
1492 +    tao - the Tao solver context
1493 -    mctx - [optional] monitoring context
1494 
1495    Options Database Keys:
1496 +    -tao_monitor        - sets TaoMonitorDefault()
1497 .    -tao_smonitor       - sets short monitor
1498 .    -tao_cmonitor       - same as smonitor plus constraint norm
1499 .    -tao_view_solution   - view solution at each iteration
1500 .    -tao_view_gradient   - view gradient at each iteration
1501 .    -tao_view_ls_residual - view least-squares residual vector at each iteration
1502 -    -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.
1503 
1504    Notes:
1505    Several different monitoring routines may be set by calling
1506    TaoSetMonitor() multiple times; all will be called in the
1507    order in which they were set.
1508 
1509    Fortran Notes:
1510     Only one monitor function may be set
1511 
1512    Level: intermediate
1513 
1514 .seealso: `TaoMonitorDefault()`, `TaoCancelMonitors()`, `TaoSetDestroyRoutine()`
1515 @*/
1516 PetscErrorCode TaoSetMonitor(Tao tao, PetscErrorCode (*func)(Tao, void*), void *ctx,PetscErrorCode (*dest)(void**))
1517 {
1518   PetscInt       i;
1519   PetscBool      identical;
1520 
1521   PetscFunctionBegin;
1522   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
1523   PetscCheck(tao->numbermonitors < MAXTAOMONITORS,PetscObjectComm((PetscObject)tao),PETSC_ERR_SUP,"Cannot attach another monitor -- max=%d",MAXTAOMONITORS);
1524 
1525   for (i=0; i<tao->numbermonitors;i++) {
1526     PetscCall(PetscMonitorCompare((PetscErrorCode (*)(void))func,ctx,dest,(PetscErrorCode (*)(void))tao->monitor[i],tao->monitorcontext[i],tao->monitordestroy[i],&identical));
1527     if (identical) PetscFunctionReturn(0);
1528   }
1529   tao->monitor[tao->numbermonitors] = func;
1530   tao->monitorcontext[tao->numbermonitors] = (void*)ctx;
1531   tao->monitordestroy[tao->numbermonitors] = dest;
1532   ++tao->numbermonitors;
1533   PetscFunctionReturn(0);
1534 }
1535 
1536 /*@
1537    TaoCancelMonitors - Clears all the monitor functions for a Tao object.
1538 
1539    Logically Collective on Tao
1540 
1541    Input Parameters:
1542 .  tao - the Tao solver context
1543 
1544    Options Database:
1545 .  -tao_cancelmonitors - cancels all monitors that have been hardwired
1546     into a code by calls to TaoSetMonitor(), but does not cancel those
1547     set via the options database
1548 
1549    Notes:
1550    There is no way to clear one specific monitor from a Tao object.
1551 
1552    Level: advanced
1553 
1554 .seealso: `TaoMonitorDefault()`, `TaoSetMonitor()`
1555 @*/
1556 PetscErrorCode TaoCancelMonitors(Tao tao)
1557 {
1558   PetscInt       i;
1559 
1560   PetscFunctionBegin;
1561   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
1562   for (i=0;i<tao->numbermonitors;i++) {
1563     if (tao->monitordestroy[i]) {
1564       PetscCall((*tao->monitordestroy[i])(&tao->monitorcontext[i]));
1565     }
1566   }
1567   tao->numbermonitors = 0;
1568   PetscFunctionReturn(0);
1569 }
1570 
1571 /*@
1572    TaoMonitorDefault - Default routine for monitoring progress of the
1573    Tao solvers (default).  This monitor prints the function value and gradient
1574    norm at each iteration.  It can be turned on from the command line using the
1575    -tao_monitor option
1576 
1577    Collective on Tao
1578 
1579    Input Parameters:
1580 +  tao - the Tao context
1581 -  ctx - PetscViewer context or NULL
1582 
1583    Options Database Keys:
1584 .  -tao_monitor - turn on default monitoring
1585 
1586    Level: advanced
1587 
1588 .seealso: `TaoDefaultSMonitor()`, `TaoSetMonitor()`
1589 @*/
1590 PetscErrorCode TaoMonitorDefault(Tao tao, void *ctx)
1591 {
1592   PetscInt       its, tabs;
1593   PetscReal      fct,gnorm;
1594   PetscViewer    viewer = (PetscViewer)ctx;
1595 
1596   PetscFunctionBegin;
1597   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
1598   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1599   its = tao->niter;
1600   fct = tao->fc;
1601   gnorm = tao->residual;
1602   PetscCall(PetscViewerASCIIGetTab(viewer, &tabs));
1603   PetscCall(PetscViewerASCIISetTab(viewer, ((PetscObject)tao)->tablevel));
1604   if (its == 0 && ((PetscObject)tao)->prefix && !tao->header_printed) {
1605      PetscCall(PetscViewerASCIIPrintf(viewer,"  Iteration information for %s solve.\n",((PetscObject)tao)->prefix));
1606      tao->header_printed = PETSC_TRUE;
1607    }
1608   PetscCall(PetscViewerASCIIPrintf(viewer,"%3" PetscInt_FMT " TAO,",its));
1609   PetscCall(PetscViewerASCIIPrintf(viewer,"  Function value: %g,",(double)fct));
1610   if (gnorm >= PETSC_INFINITY) {
1611     PetscCall(PetscViewerASCIIPrintf(viewer,"  Residual: Inf \n"));
1612   } else {
1613     PetscCall(PetscViewerASCIIPrintf(viewer,"  Residual: %g \n",(double)gnorm));
1614   }
1615   PetscCall(PetscViewerASCIISetTab(viewer, tabs));
1616   PetscFunctionReturn(0);
1617 }
1618 
1619 /*@
1620    TaoDefaultGMonitor - Default routine for monitoring progress of the
1621    Tao solvers (default) with extra detail on the globalization method.
1622    This monitor prints the function value and gradient norm at each
1623    iteration, as well as the step size and trust radius. Note that the
1624    step size and trust radius may be the same for some algorithms.
1625    It can be turned on from the command line using the
1626    -tao_gmonitor option
1627 
1628    Collective on Tao
1629 
1630    Input Parameters:
1631 +  tao - the Tao context
1632 -  ctx - PetscViewer context or NULL
1633 
1634    Options Database Keys:
1635 .  -tao_gmonitor - turn on monitoring with globalization information
1636 
1637    Level: advanced
1638 
1639 .seealso: `TaoDefaultSMonitor()`, `TaoSetMonitor()`
1640 @*/
1641 PetscErrorCode TaoDefaultGMonitor(Tao tao, void *ctx)
1642 {
1643   PetscInt       its, tabs;
1644   PetscReal      fct,gnorm,stp,tr;
1645   PetscViewer    viewer = (PetscViewer)ctx;
1646 
1647   PetscFunctionBegin;
1648   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
1649   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1650   its = tao->niter;
1651   fct = tao->fc;
1652   gnorm = tao->residual;
1653   stp = tao->step;
1654   tr = tao->trust;
1655   PetscCall(PetscViewerASCIIGetTab(viewer, &tabs));
1656   PetscCall(PetscViewerASCIISetTab(viewer, ((PetscObject)tao)->tablevel));
1657   if (its == 0 && ((PetscObject)tao)->prefix && !tao->header_printed) {
1658      PetscCall(PetscViewerASCIIPrintf(viewer,"  Iteration information for %s solve.\n",((PetscObject)tao)->prefix));
1659      tao->header_printed = PETSC_TRUE;
1660    }
1661   PetscCall(PetscViewerASCIIPrintf(viewer,"%3" PetscInt_FMT " TAO,",its));
1662   PetscCall(PetscViewerASCIIPrintf(viewer,"  Function value: %g,",(double)fct));
1663   if (gnorm >= PETSC_INFINITY) {
1664     PetscCall(PetscViewerASCIIPrintf(viewer,"  Residual: Inf,"));
1665   } else {
1666     PetscCall(PetscViewerASCIIPrintf(viewer,"  Residual: %g,",(double)gnorm));
1667   }
1668   PetscCall(PetscViewerASCIIPrintf(viewer,"  Step: %g,  Trust: %g\n",(double)stp,(double)tr));
1669   PetscCall(PetscViewerASCIISetTab(viewer, tabs));
1670   PetscFunctionReturn(0);
1671 }
1672 
1673 /*@
1674    TaoDefaultSMonitor - Default routine for monitoring progress of the
1675    solver. Same as TaoMonitorDefault() except
1676    it prints fewer digits of the residual as the residual gets smaller.
1677    This is because the later digits are meaningless and are often
1678    different on different machines; by using this routine different
1679    machines will usually generate the same output. It can be turned on
1680    by using the -tao_smonitor option
1681 
1682    Collective on Tao
1683 
1684    Input Parameters:
1685 +  tao - the Tao context
1686 -  ctx - PetscViewer context of type ASCII
1687 
1688    Options Database Keys:
1689 .  -tao_smonitor - turn on default short monitoring
1690 
1691    Level: advanced
1692 
1693 .seealso: `TaoMonitorDefault()`, `TaoSetMonitor()`
1694 @*/
1695 PetscErrorCode TaoDefaultSMonitor(Tao tao, void *ctx)
1696 {
1697   PetscInt       its, tabs;
1698   PetscReal      fct,gnorm;
1699   PetscViewer    viewer = (PetscViewer)ctx;
1700 
1701   PetscFunctionBegin;
1702   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
1703   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1704   its = tao->niter;
1705   fct = tao->fc;
1706   gnorm = tao->residual;
1707   PetscCall(PetscViewerASCIIGetTab(viewer, &tabs));
1708   PetscCall(PetscViewerASCIISetTab(viewer, ((PetscObject)tao)->tablevel));
1709   PetscCall(PetscViewerASCIIPrintf(viewer,"iter = %3" PetscInt_FMT ",",its));
1710   PetscCall(PetscViewerASCIIPrintf(viewer," Function value %g,",(double)fct));
1711   if (gnorm >= PETSC_INFINITY) {
1712     PetscCall(PetscViewerASCIIPrintf(viewer," Residual: Inf \n"));
1713   } else if (gnorm > 1.e-6) {
1714     PetscCall(PetscViewerASCIIPrintf(viewer," Residual: %g \n",(double)gnorm));
1715   } else if (gnorm > 1.e-11) {
1716     PetscCall(PetscViewerASCIIPrintf(viewer," Residual: < 1.0e-6 \n"));
1717   } else {
1718     PetscCall(PetscViewerASCIIPrintf(viewer," Residual: < 1.0e-11 \n"));
1719   }
1720   PetscCall(PetscViewerASCIISetTab(viewer, tabs));
1721   PetscFunctionReturn(0);
1722 }
1723 
1724 /*@
1725    TaoDefaultCMonitor - same as TaoMonitorDefault() except
1726    it prints the norm of the constraints function. It can be turned on
1727    from the command line using the -tao_cmonitor option
1728 
1729    Collective on Tao
1730 
1731    Input Parameters:
1732 +  tao - the Tao context
1733 -  ctx - PetscViewer context or NULL
1734 
1735    Options Database Keys:
1736 .  -tao_cmonitor - monitor the constraints
1737 
1738    Level: advanced
1739 
1740 .seealso: `TaoMonitorDefault()`, `TaoSetMonitor()`
1741 @*/
1742 PetscErrorCode TaoDefaultCMonitor(Tao tao, void *ctx)
1743 {
1744   PetscInt       its, tabs;
1745   PetscReal      fct,gnorm;
1746   PetscViewer    viewer = (PetscViewer)ctx;
1747 
1748   PetscFunctionBegin;
1749   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
1750   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1751   its = tao->niter;
1752   fct = tao->fc;
1753   gnorm = tao->residual;
1754   PetscCall(PetscViewerASCIIGetTab(viewer, &tabs));
1755   PetscCall(PetscViewerASCIISetTab(viewer, ((PetscObject)tao)->tablevel));
1756   PetscCall(PetscViewerASCIIPrintf(viewer,"iter = %" PetscInt_FMT ",",its));
1757   PetscCall(PetscViewerASCIIPrintf(viewer," Function value: %g,",(double)fct));
1758   PetscCall(PetscViewerASCIIPrintf(viewer,"  Residual: %g ",(double)gnorm));
1759   PetscCall(PetscViewerASCIIPrintf(viewer,"  Constraint: %g \n",(double)tao->cnorm));
1760   PetscCall(PetscViewerASCIISetTab(viewer, tabs));
1761   PetscFunctionReturn(0);
1762 }
1763 
1764 /*@C
1765    TaoSolutionMonitor - Views the solution at each iteration
1766    It can be turned on from the command line using the
1767    -tao_view_solution option
1768 
1769    Collective on Tao
1770 
1771    Input Parameters:
1772 +  tao - the Tao context
1773 -  ctx - PetscViewer context or NULL
1774 
1775    Options Database Keys:
1776 .  -tao_view_solution - view the solution
1777 
1778    Level: advanced
1779 
1780 .seealso: `TaoDefaultSMonitor()`, `TaoSetMonitor()`
1781 @*/
1782 PetscErrorCode TaoSolutionMonitor(Tao tao, void *ctx)
1783 {
1784   PetscViewer    viewer  = (PetscViewer)ctx;
1785 
1786   PetscFunctionBegin;
1787   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
1788   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1789   PetscCall(VecView(tao->solution,viewer));
1790   PetscFunctionReturn(0);
1791 }
1792 
1793 /*@C
1794    TaoGradientMonitor - Views the gradient at each iteration
1795    It can be turned on from the command line using the
1796    -tao_view_gradient option
1797 
1798    Collective on Tao
1799 
1800    Input Parameters:
1801 +  tao - the Tao context
1802 -  ctx - PetscViewer context or NULL
1803 
1804    Options Database Keys:
1805 .  -tao_view_gradient - view the gradient at each iteration
1806 
1807    Level: advanced
1808 
1809 .seealso: `TaoDefaultSMonitor()`, `TaoSetMonitor()`
1810 @*/
1811 PetscErrorCode TaoGradientMonitor(Tao tao, void *ctx)
1812 {
1813   PetscViewer    viewer = (PetscViewer)ctx;
1814 
1815   PetscFunctionBegin;
1816   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
1817   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1818   PetscCall(VecView(tao->gradient,viewer));
1819   PetscFunctionReturn(0);
1820 }
1821 
1822 /*@C
1823    TaoStepDirectionMonitor - Views the step-direction at each iteration
1824 
1825    Collective on Tao
1826 
1827    Input Parameters:
1828 +  tao - the Tao context
1829 -  ctx - PetscViewer context or NULL
1830 
1831    Options Database Keys:
1832 .  -tao_view_gradient - view the gradient at each iteration
1833 
1834    Level: advanced
1835 
1836 .seealso: `TaoDefaultSMonitor()`, `TaoSetMonitor()`
1837 @*/
1838 PetscErrorCode TaoStepDirectionMonitor(Tao tao, void *ctx)
1839 {
1840   PetscViewer    viewer = (PetscViewer)ctx;
1841 
1842   PetscFunctionBegin;
1843   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
1844   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1845   PetscCall(VecView(tao->stepdirection,viewer));
1846   PetscFunctionReturn(0);
1847 }
1848 
1849 /*@C
1850    TaoDrawSolutionMonitor - Plots the solution at each iteration
1851    It can be turned on from the command line using the
1852    -tao_draw_solution option
1853 
1854    Collective on Tao
1855 
1856    Input Parameters:
1857 +  tao - the Tao context
1858 -  ctx - TaoMonitorDraw context
1859 
1860    Options Database Keys:
1861 .  -tao_draw_solution - draw the solution at each iteration
1862 
1863    Level: advanced
1864 
1865 .seealso: `TaoSolutionMonitor()`, `TaoSetMonitor()`, `TaoDrawGradientMonitor`
1866 @*/
1867 PetscErrorCode TaoDrawSolutionMonitor(Tao tao, void *ctx)
1868 {
1869   TaoMonitorDrawCtx ictx = (TaoMonitorDrawCtx)ctx;
1870 
1871   PetscFunctionBegin;
1872   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
1873   if (!(((ictx->howoften > 0) && (!(tao->niter % ictx->howoften))) || ((ictx->howoften == -1) && tao->reason))) PetscFunctionReturn(0);
1874   PetscCall(VecView(tao->solution,ictx->viewer));
1875   PetscFunctionReturn(0);
1876 }
1877 
1878 /*@C
1879    TaoDrawGradientMonitor - Plots the gradient at each iteration
1880    It can be turned on from the command line using the
1881    -tao_draw_gradient option
1882 
1883    Collective on Tao
1884 
1885    Input Parameters:
1886 +  tao - the Tao context
1887 -  ctx - PetscViewer context
1888 
1889    Options Database Keys:
1890 .  -tao_draw_gradient - draw the gradient at each iteration
1891 
1892    Level: advanced
1893 
1894 .seealso: `TaoGradientMonitor()`, `TaoSetMonitor()`, `TaoDrawSolutionMonitor`
1895 @*/
1896 PetscErrorCode TaoDrawGradientMonitor(Tao tao, void *ctx)
1897 {
1898   TaoMonitorDrawCtx ictx = (TaoMonitorDrawCtx)ctx;
1899 
1900   PetscFunctionBegin;
1901   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
1902   if (!(((ictx->howoften > 0) && (!(tao->niter % ictx->howoften))) || ((ictx->howoften == -1) && tao->reason))) PetscFunctionReturn(0);
1903   PetscCall(VecView(tao->gradient,ictx->viewer));
1904   PetscFunctionReturn(0);
1905 }
1906 
1907 /*@C
1908    TaoDrawStepMonitor - Plots the step direction at each iteration
1909 
1910    Collective on Tao
1911 
1912    Input Parameters:
1913 +  tao - the Tao context
1914 -  ctx - PetscViewer context
1915 
1916    Options Database Keys:
1917 .  -tao_draw_step - draw the step direction at each iteration
1918 
1919    Level: advanced
1920 
1921 .seealso: `TaoSetMonitor()`, `TaoDrawSolutionMonitor`
1922 @*/
1923 PetscErrorCode TaoDrawStepMonitor(Tao tao, void *ctx)
1924 {
1925   PetscViewer    viewer = (PetscViewer)ctx;
1926 
1927   PetscFunctionBegin;
1928   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
1929   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1930   PetscCall(VecView(tao->stepdirection,viewer));
1931   PetscFunctionReturn(0);
1932 }
1933 
1934 /*@C
1935    TaoResidualMonitor - Views the least-squares residual at each iteration
1936 
1937    Collective on Tao
1938 
1939    Input Parameters:
1940 +  tao - the Tao context
1941 -  ctx - PetscViewer context or NULL
1942 
1943    Options Database Keys:
1944 .  -tao_view_ls_residual - view the least-squares residual at each iteration
1945 
1946    Level: advanced
1947 
1948 .seealso: `TaoDefaultSMonitor()`, `TaoSetMonitor()`
1949 @*/
1950 PetscErrorCode TaoResidualMonitor(Tao tao, void *ctx)
1951 {
1952   PetscViewer    viewer  = (PetscViewer)ctx;
1953 
1954   PetscFunctionBegin;
1955   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
1956   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1957   PetscCall(VecView(tao->ls_res,viewer));
1958   PetscFunctionReturn(0);
1959 }
1960 
1961 /*@
1962    TaoDefaultConvergenceTest - Determines whether the solver should continue iterating
1963    or terminate.
1964 
1965    Collective on Tao
1966 
1967    Input Parameters:
1968 +  tao - the Tao context
1969 -  dummy - unused dummy context
1970 
1971    Output Parameter:
1972 .  reason - for terminating
1973 
1974    Notes:
1975    This routine checks the residual in the optimality conditions, the
1976    relative residual in the optimity conditions, the number of function
1977    evaluations, and the function value to test convergence.  Some
1978    solvers may use different convergence routines.
1979 
1980    Level: developer
1981 
1982 .seealso: `TaoSetTolerances()`, `TaoGetConvergedReason()`, `TaoSetConvergedReason()`
1983 @*/
1984 
1985 PetscErrorCode TaoDefaultConvergenceTest(Tao tao,void *dummy)
1986 {
1987   PetscInt           niter=tao->niter, nfuncs=PetscMax(tao->nfuncs,tao->nfuncgrads);
1988   PetscInt           max_funcs=tao->max_funcs;
1989   PetscReal          gnorm=tao->residual, gnorm0=tao->gnorm0;
1990   PetscReal          f=tao->fc, steptol=tao->steptol,trradius=tao->step;
1991   PetscReal          gatol=tao->gatol,grtol=tao->grtol,gttol=tao->gttol;
1992   PetscReal          catol=tao->catol,crtol=tao->crtol;
1993   PetscReal          fmin=tao->fmin, cnorm=tao->cnorm;
1994   TaoConvergedReason reason=tao->reason;
1995 
1996   PetscFunctionBegin;
1997   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
1998   if (reason != TAO_CONTINUE_ITERATING) PetscFunctionReturn(0);
1999 
2000   if (PetscIsInfOrNanReal(f)) {
2001     PetscCall(PetscInfo(tao,"Failed to converged, function value is Inf or NaN\n"));
2002     reason = TAO_DIVERGED_NAN;
2003   } else if (f <= fmin && cnorm <=catol) {
2004     PetscCall(PetscInfo(tao,"Converged due to function value %g < minimum function value %g\n", (double)f,(double)fmin));
2005     reason = TAO_CONVERGED_MINF;
2006   } else if (gnorm<= gatol && cnorm <=catol) {
2007     PetscCall(PetscInfo(tao,"Converged due to residual norm ||g(X)||=%g < %g\n",(double)gnorm,(double)gatol));
2008     reason = TAO_CONVERGED_GATOL;
2009   } else if (f!=0 && PetscAbsReal(gnorm/f) <= grtol && cnorm <= crtol) {
2010     PetscCall(PetscInfo(tao,"Converged due to residual ||g(X)||/|f(X)| =%g < %g\n",(double)(gnorm/f),(double)grtol));
2011     reason = TAO_CONVERGED_GRTOL;
2012   } else if (gnorm0 != 0 && ((gttol == 0 && gnorm == 0) || gnorm/gnorm0 < gttol) && cnorm <= crtol) {
2013     PetscCall(PetscInfo(tao,"Converged due to relative residual norm ||g(X)||/||g(X0)|| = %g < %g\n",(double)(gnorm/gnorm0),(double)gttol));
2014     reason = TAO_CONVERGED_GTTOL;
2015   } else if (max_funcs >=0 && nfuncs > max_funcs) {
2016     PetscCall(PetscInfo(tao,"Exceeded maximum number of function evaluations: %" PetscInt_FMT " > %" PetscInt_FMT "\n", nfuncs,max_funcs));
2017     reason = TAO_DIVERGED_MAXFCN;
2018   } else if (tao->lsflag != 0) {
2019     PetscCall(PetscInfo(tao,"Tao Line Search failure.\n"));
2020     reason = TAO_DIVERGED_LS_FAILURE;
2021   } else if (trradius < steptol && niter > 0) {
2022     PetscCall(PetscInfo(tao,"Trust region/step size too small: %g < %g\n", (double)trradius,(double)steptol));
2023     reason = TAO_CONVERGED_STEPTOL;
2024   } else if (niter >= tao->max_it) {
2025     PetscCall(PetscInfo(tao,"Exceeded maximum number of iterations: %" PetscInt_FMT " > %" PetscInt_FMT "\n",niter,tao->max_it));
2026     reason = TAO_DIVERGED_MAXITS;
2027   } else {
2028     reason = TAO_CONTINUE_ITERATING;
2029   }
2030   tao->reason = reason;
2031   PetscFunctionReturn(0);
2032 }
2033 
2034 /*@C
2035    TaoSetOptionsPrefix - Sets the prefix used for searching for all
2036    TAO options in the database.
2037 
2038    Logically Collective on Tao
2039 
2040    Input Parameters:
2041 +  tao - the Tao context
2042 -  prefix - the prefix string to prepend to all TAO option requests
2043 
2044    Notes:
2045    A hyphen (-) must NOT be given at the beginning of the prefix name.
2046    The first character of all runtime options is AUTOMATICALLY the hyphen.
2047 
2048    For example, to distinguish between the runtime options for two
2049    different TAO solvers, one could call
2050 .vb
2051       TaoSetOptionsPrefix(tao1,"sys1_")
2052       TaoSetOptionsPrefix(tao2,"sys2_")
2053 .ve
2054 
2055    This would enable use of different options for each system, such as
2056 .vb
2057       -sys1_tao_method blmvm -sys1_tao_grtol 1.e-3
2058       -sys2_tao_method lmvm  -sys2_tao_grtol 1.e-4
2059 .ve
2060 
2061    Level: advanced
2062 
2063 .seealso: `TaoAppendOptionsPrefix()`, `TaoGetOptionsPrefix()`
2064 @*/
2065 
2066 PetscErrorCode TaoSetOptionsPrefix(Tao tao, const char p[])
2067 {
2068   PetscFunctionBegin;
2069   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
2070   PetscCall(PetscObjectSetOptionsPrefix((PetscObject)tao,p));
2071   if (tao->linesearch) {
2072     PetscCall(TaoLineSearchSetOptionsPrefix(tao->linesearch,p));
2073   }
2074   if (tao->ksp) {
2075     PetscCall(KSPSetOptionsPrefix(tao->ksp,p));
2076   }
2077   PetscFunctionReturn(0);
2078 }
2079 
2080 /*@C
2081    TaoAppendOptionsPrefix - Appends to the prefix used for searching for all
2082    TAO options in the database.
2083 
2084    Logically Collective on Tao
2085 
2086    Input Parameters:
2087 +  tao - the Tao solver context
2088 -  prefix - the prefix string to prepend to all TAO option requests
2089 
2090    Notes:
2091    A hyphen (-) must NOT be given at the beginning of the prefix name.
2092    The first character of all runtime options is AUTOMATICALLY the hyphen.
2093 
2094    Level: advanced
2095 
2096 .seealso: `TaoSetOptionsPrefix()`, `TaoGetOptionsPrefix()`
2097 @*/
2098 PetscErrorCode TaoAppendOptionsPrefix(Tao tao, const char p[])
2099 {
2100   PetscFunctionBegin;
2101   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
2102   PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)tao,p));
2103   if (tao->linesearch) {
2104     PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)tao->linesearch,p));
2105   }
2106   if (tao->ksp) {
2107     PetscCall(KSPAppendOptionsPrefix(tao->ksp,p));
2108   }
2109   PetscFunctionReturn(0);
2110 }
2111 
2112 /*@C
2113   TaoGetOptionsPrefix - Gets the prefix used for searching for all
2114   TAO options in the database
2115 
2116   Not Collective
2117 
2118   Input Parameters:
2119 . tao - the Tao context
2120 
2121   Output Parameters:
2122 . prefix - pointer to the prefix string used is returned
2123 
2124   Notes:
2125     On the fortran side, the user should pass in a string 'prefix' of
2126   sufficient length to hold the prefix.
2127 
2128   Level: advanced
2129 
2130 .seealso: `TaoSetOptionsPrefix()`, `TaoAppendOptionsPrefix()`
2131 @*/
2132 PetscErrorCode TaoGetOptionsPrefix(Tao tao, const char *p[])
2133 {
2134   PetscFunctionBegin;
2135   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
2136   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)tao,p));
2137   PetscFunctionReturn(0);
2138 }
2139 
2140 /*@C
2141    TaoSetType - Sets the method for the unconstrained minimization solver.
2142 
2143    Collective on Tao
2144 
2145    Input Parameters:
2146 +  solver - the Tao solver context
2147 -  type - a known method
2148 
2149    Options Database Key:
2150 .  -tao_type <type> - Sets the method; use -help for a list
2151    of available methods (for instance, "-tao_type lmvm" or "-tao_type tron")
2152 
2153    Available methods include:
2154 +    nls - Newton's method with line search for unconstrained minimization
2155 .    ntr - Newton's method with trust region for unconstrained minimization
2156 .    ntl - Newton's method with trust region, line search for unconstrained minimization
2157 .    lmvm - Limited memory variable metric method for unconstrained minimization
2158 .    cg - Nonlinear conjugate gradient method for unconstrained minimization
2159 .    nm - Nelder-Mead algorithm for derivate-free unconstrained minimization
2160 .    tron - Newton Trust Region method for bound constrained minimization
2161 .    gpcg - Newton Trust Region method for quadratic bound constrained minimization
2162 .    blmvm - Limited memory variable metric method for bound constrained minimization
2163 -    pounders - Model-based algorithm pounder extended for nonlinear least squares
2164 
2165   Level: intermediate
2166 
2167 .seealso: `TaoCreate()`, `TaoGetType()`, `TaoType`
2168 
2169 @*/
2170 PetscErrorCode TaoSetType(Tao tao, TaoType type)
2171 {
2172   PetscErrorCode (*create_xxx)(Tao);
2173   PetscBool      issame;
2174 
2175   PetscFunctionBegin;
2176   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
2177 
2178   PetscCall(PetscObjectTypeCompare((PetscObject)tao,type,&issame));
2179   if (issame) PetscFunctionReturn(0);
2180 
2181   PetscCall(PetscFunctionListFind(TaoList, type, (void(**)(void))&create_xxx));
2182   PetscCheck(create_xxx,PetscObjectComm((PetscObject)tao),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested Tao type %s",type);
2183 
2184   /* Destroy the existing solver information */
2185   if (tao->ops->destroy) {
2186     PetscCall((*tao->ops->destroy)(tao));
2187   }
2188   PetscCall(KSPDestroy(&tao->ksp));
2189   PetscCall(TaoLineSearchDestroy(&tao->linesearch));
2190   PetscCall(VecDestroy(&tao->gradient));
2191   PetscCall(VecDestroy(&tao->stepdirection));
2192 
2193   tao->ops->setup = NULL;
2194   tao->ops->solve = NULL;
2195   tao->ops->view  = NULL;
2196   tao->ops->setfromoptions = NULL;
2197   tao->ops->destroy = NULL;
2198 
2199   tao->setupcalled = PETSC_FALSE;
2200 
2201   PetscCall((*create_xxx)(tao));
2202   PetscCall(PetscObjectChangeTypeName((PetscObject)tao,type));
2203   PetscFunctionReturn(0);
2204 }
2205 
2206 /*MC
2207    TaoRegister - Adds a method to the TAO package for unconstrained minimization.
2208 
2209    Synopsis:
2210    TaoRegister(char *name_solver,char *path,char *name_Create,PetscErrorCode (*routine_Create)(Tao))
2211 
2212    Not collective
2213 
2214    Input Parameters:
2215 +  sname - name of a new user-defined solver
2216 -  func - routine to Create method context
2217 
2218    Notes:
2219    TaoRegister() may be called multiple times to add several user-defined solvers.
2220 
2221    Sample usage:
2222 .vb
2223    TaoRegister("my_solver",MySolverCreate);
2224 .ve
2225 
2226    Then, your solver can be chosen with the procedural interface via
2227 $     TaoSetType(tao,"my_solver")
2228    or at runtime via the option
2229 $     -tao_type my_solver
2230 
2231    Level: advanced
2232 
2233 .seealso: `TaoRegisterAll()`, `TaoRegisterDestroy()`
2234 M*/
2235 PetscErrorCode TaoRegister(const char sname[], PetscErrorCode (*func)(Tao))
2236 {
2237   PetscFunctionBegin;
2238   PetscCall(TaoInitializePackage());
2239   PetscCall(PetscFunctionListAdd(&TaoList,sname,(void (*)(void))func));
2240   PetscFunctionReturn(0);
2241 }
2242 
2243 /*@C
2244    TaoRegisterDestroy - Frees the list of minimization solvers that were
2245    registered by TaoRegisterDynamic().
2246 
2247    Not Collective
2248 
2249    Level: advanced
2250 
2251 .seealso: `TaoRegisterAll()`, `TaoRegister()`
2252 @*/
2253 PetscErrorCode TaoRegisterDestroy(void)
2254 {
2255   PetscFunctionBegin;
2256   PetscCall(PetscFunctionListDestroy(&TaoList));
2257   TaoRegisterAllCalled = PETSC_FALSE;
2258   PetscFunctionReturn(0);
2259 }
2260 
2261 /*@
2262    TaoGetIterationNumber - Gets the number of Tao iterations completed
2263    at this time.
2264 
2265    Not Collective
2266 
2267    Input Parameter:
2268 .  tao - Tao context
2269 
2270    Output Parameter:
2271 .  iter - iteration number
2272 
2273    Notes:
2274    For example, during the computation of iteration 2 this would return 1.
2275 
2276    Level: intermediate
2277 
2278 .seealso: `TaoGetLinearSolveIterations()`, `TaoGetResidualNorm()`, `TaoGetObjective()`
2279 @*/
2280 PetscErrorCode  TaoGetIterationNumber(Tao tao,PetscInt *iter)
2281 {
2282   PetscFunctionBegin;
2283   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
2284   PetscValidIntPointer(iter,2);
2285   *iter = tao->niter;
2286   PetscFunctionReturn(0);
2287 }
2288 
2289 /*@
2290    TaoGetResidualNorm - Gets the current value of the norm of the residual
2291    at this time.
2292 
2293    Not Collective
2294 
2295    Input Parameter:
2296 .  tao - Tao context
2297 
2298    Output Parameter:
2299 .  value - the current value
2300 
2301    Level: intermediate
2302 
2303    Developer Note: This is the 2-norm of the residual, we cannot use TaoGetGradientNorm() because that has
2304                    a different meaning. For some reason Tao sometimes calls the gradient the residual.
2305 
2306 .seealso: `TaoGetLinearSolveIterations()`, `TaoGetIterationNumber()`, `TaoGetObjective()`
2307 @*/
2308 PetscErrorCode TaoGetResidualNorm(Tao tao,PetscReal *value)
2309 {
2310   PetscFunctionBegin;
2311   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
2312   PetscValidRealPointer(value,2);
2313   *value = tao->residual;
2314   PetscFunctionReturn(0);
2315 }
2316 
2317 /*@
2318    TaoSetIterationNumber - Sets the current iteration number.
2319 
2320    Logically Collective on Tao
2321 
2322    Input Parameters:
2323 +  tao - Tao context
2324 -  iter - iteration number
2325 
2326    Level: developer
2327 
2328 .seealso: `TaoGetLinearSolveIterations()`
2329 @*/
2330 PetscErrorCode  TaoSetIterationNumber(Tao tao,PetscInt iter)
2331 {
2332   PetscFunctionBegin;
2333   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
2334   PetscValidLogicalCollectiveInt(tao,iter,2);
2335   PetscCall(PetscObjectSAWsTakeAccess((PetscObject)tao));
2336   tao->niter = iter;
2337   PetscCall(PetscObjectSAWsGrantAccess((PetscObject)tao));
2338   PetscFunctionReturn(0);
2339 }
2340 
2341 /*@
2342    TaoGetTotalIterationNumber - Gets the total number of Tao iterations
2343    completed. This number keeps accumulating if multiple solves
2344    are called with the Tao object.
2345 
2346    Not Collective
2347 
2348    Input Parameter:
2349 .  tao - Tao context
2350 
2351    Output Parameter:
2352 .  iter - iteration number
2353 
2354    Notes:
2355    The total iteration count is updated after each solve, if there is a current
2356    TaoSolve() in progress then those iterations are not yet counted.
2357 
2358    Level: intermediate
2359 
2360 .seealso: `TaoGetLinearSolveIterations()`
2361 @*/
2362 PetscErrorCode  TaoGetTotalIterationNumber(Tao tao,PetscInt *iter)
2363 {
2364   PetscFunctionBegin;
2365   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
2366   PetscValidIntPointer(iter,2);
2367   *iter = tao->ntotalits;
2368   PetscFunctionReturn(0);
2369 }
2370 
2371 /*@
2372    TaoSetTotalIterationNumber - Sets the current total iteration number.
2373 
2374    Logically Collective on Tao
2375 
2376    Input Parameters:
2377 +  tao - Tao context
2378 -  iter - iteration number
2379 
2380    Level: developer
2381 
2382 .seealso: `TaoGetLinearSolveIterations()`
2383 @*/
2384 PetscErrorCode  TaoSetTotalIterationNumber(Tao tao,PetscInt iter)
2385 {
2386   PetscFunctionBegin;
2387   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
2388   PetscValidLogicalCollectiveInt(tao,iter,2);
2389   PetscCall(PetscObjectSAWsTakeAccess((PetscObject)tao));
2390   tao->ntotalits = iter;
2391   PetscCall(PetscObjectSAWsGrantAccess((PetscObject)tao));
2392   PetscFunctionReturn(0);
2393 }
2394 
2395 /*@
2396   TaoSetConvergedReason - Sets the termination flag on a Tao object
2397 
2398   Logically Collective on Tao
2399 
2400   Input Parameters:
2401 + tao - the Tao context
2402 - reason - one of
2403 $     TAO_CONVERGED_ATOL (2),
2404 $     TAO_CONVERGED_RTOL (3),
2405 $     TAO_CONVERGED_STEPTOL (4),
2406 $     TAO_CONVERGED_MINF (5),
2407 $     TAO_CONVERGED_USER (6),
2408 $     TAO_DIVERGED_MAXITS (-2),
2409 $     TAO_DIVERGED_NAN (-4),
2410 $     TAO_DIVERGED_MAXFCN (-5),
2411 $     TAO_DIVERGED_LS_FAILURE (-6),
2412 $     TAO_DIVERGED_TR_REDUCTION (-7),
2413 $     TAO_DIVERGED_USER (-8),
2414 $     TAO_CONTINUE_ITERATING (0)
2415 
2416    Level: intermediate
2417 
2418 @*/
2419 PetscErrorCode TaoSetConvergedReason(Tao tao, TaoConvergedReason reason)
2420 {
2421   PetscFunctionBegin;
2422   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
2423   PetscValidLogicalCollectiveEnum(tao,reason,2);
2424   tao->reason = reason;
2425   PetscFunctionReturn(0);
2426 }
2427 
2428 /*@
2429    TaoGetConvergedReason - Gets the reason the Tao iteration was stopped.
2430 
2431    Not Collective
2432 
2433    Input Parameter:
2434 .  tao - the Tao solver context
2435 
2436    Output Parameter:
2437 .  reason - one of
2438 $  TAO_CONVERGED_GATOL (3)           ||g(X)|| < gatol
2439 $  TAO_CONVERGED_GRTOL (4)           ||g(X)|| / f(X)  < grtol
2440 $  TAO_CONVERGED_GTTOL (5)           ||g(X)|| / ||g(X0)|| < gttol
2441 $  TAO_CONVERGED_STEPTOL (6)         step size small
2442 $  TAO_CONVERGED_MINF (7)            F < F_min
2443 $  TAO_CONVERGED_USER (8)            User defined
2444 $  TAO_DIVERGED_MAXITS (-2)          its > maxits
2445 $  TAO_DIVERGED_NAN (-4)             Numerical problems
2446 $  TAO_DIVERGED_MAXFCN (-5)          fevals > max_funcsals
2447 $  TAO_DIVERGED_LS_FAILURE (-6)      line search failure
2448 $  TAO_DIVERGED_TR_REDUCTION (-7)    trust region failure
2449 $  TAO_DIVERGED_USER(-8)             (user defined)
2450 $  TAO_CONTINUE_ITERATING (0)
2451 
2452    where
2453 +  X - current solution
2454 .  X0 - initial guess
2455 .  f(X) - current function value
2456 .  f(X*) - true solution (estimated)
2457 .  g(X) - current gradient
2458 .  its - current iterate number
2459 .  maxits - maximum number of iterates
2460 .  fevals - number of function evaluations
2461 -  max_funcsals - maximum number of function evaluations
2462 
2463    Level: intermediate
2464 
2465 .seealso: `TaoSetConvergenceTest()`, `TaoSetTolerances()`
2466 
2467 @*/
2468 PetscErrorCode TaoGetConvergedReason(Tao tao, TaoConvergedReason *reason)
2469 {
2470   PetscFunctionBegin;
2471   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
2472   PetscValidPointer(reason,2);
2473   *reason = tao->reason;
2474   PetscFunctionReturn(0);
2475 }
2476 
2477 /*@
2478    TaoGetSolutionStatus - Get the current iterate, objective value,
2479    residual, infeasibility, and termination
2480 
2481    Not Collective
2482 
2483    Input Parameter:
2484 .  tao - the Tao context
2485 
2486    Output Parameters:
2487 +  iterate - the current iterate number (>=0)
2488 .  f - the current function value
2489 .  gnorm - the square of the gradient norm, duality gap, or other measure indicating distance from optimality.
2490 .  cnorm - the infeasibility of the current solution with regard to the constraints.
2491 .  xdiff - the step length or trust region radius of the most recent iterate.
2492 -  reason - The termination reason, which can equal TAO_CONTINUE_ITERATING
2493 
2494    Level: intermediate
2495 
2496    Note:
2497    TAO returns the values set by the solvers in the routine TaoMonitor().
2498 
2499    Note:
2500    If any of the output arguments are set to NULL, no corresponding value will be returned.
2501 
2502 .seealso: `TaoMonitor()`, `TaoGetConvergedReason()`
2503 @*/
2504 PetscErrorCode TaoGetSolutionStatus(Tao tao, PetscInt *its, PetscReal *f, PetscReal *gnorm, PetscReal *cnorm, PetscReal *xdiff, TaoConvergedReason *reason)
2505 {
2506   PetscFunctionBegin;
2507   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
2508   if (its) *its = tao->niter;
2509   if (f) *f = tao->fc;
2510   if (gnorm) *gnorm = tao->residual;
2511   if (cnorm) *cnorm = tao->cnorm;
2512   if (reason) *reason = tao->reason;
2513   if (xdiff) *xdiff = tao->step;
2514   PetscFunctionReturn(0);
2515 }
2516 
2517 /*@C
2518    TaoGetType - Gets the current Tao algorithm.
2519 
2520    Not Collective
2521 
2522    Input Parameter:
2523 .  tao - the Tao solver context
2524 
2525    Output Parameter:
2526 .  type - Tao method
2527 
2528    Level: intermediate
2529 
2530 @*/
2531 PetscErrorCode TaoGetType(Tao tao,TaoType *type)
2532 {
2533   PetscFunctionBegin;
2534   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
2535   PetscValidPointer(type,2);
2536   *type = ((PetscObject)tao)->type_name;
2537   PetscFunctionReturn(0);
2538 }
2539 
2540 /*@C
2541   TaoMonitor - Monitor the solver and the current solution.  This
2542   routine will record the iteration number and residual statistics,
2543   call any monitors specified by the user, and calls the convergence-check routine.
2544 
2545    Input Parameters:
2546 +  tao - the Tao context
2547 .  its - the current iterate number (>=0)
2548 .  f - the current objective function value
2549 .  res - the gradient norm, square root of the duality gap, or other measure indicating distince from optimality.  This measure will be recorded and
2550           used for some termination tests.
2551 .  cnorm - the infeasibility of the current solution with regard to the constraints.
2552 -  steplength - multiple of the step direction added to the previous iterate.
2553 
2554    Output Parameters:
2555 .  reason - The termination reason, which can equal TAO_CONTINUE_ITERATING
2556 
2557    Options Database Key:
2558 .  -tao_monitor - Use the default monitor, which prints statistics to standard output
2559 
2560 .seealso `TaoGetConvergedReason()`, `TaoMonitorDefault()`, `TaoSetMonitor()`
2561 
2562    Level: developer
2563 
2564 @*/
2565 PetscErrorCode TaoMonitor(Tao tao, PetscInt its, PetscReal f, PetscReal res, PetscReal cnorm, PetscReal steplength)
2566 {
2567   PetscInt       i;
2568 
2569   PetscFunctionBegin;
2570   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
2571   tao->fc = f;
2572   tao->residual = res;
2573   tao->cnorm = cnorm;
2574   tao->step = steplength;
2575   if (!its) {
2576     tao->cnorm0 = cnorm;
2577     tao->gnorm0 = res;
2578   }
2579   PetscCheck(!PetscIsInfOrNanReal(f) && !PetscIsInfOrNanReal(res),PetscObjectComm((PetscObject)tao),PETSC_ERR_USER, "User provided compute function generated Inf or NaN");
2580   for (i=0;i<tao->numbermonitors;i++) {
2581     PetscCall((*tao->monitor[i])(tao,tao->monitorcontext[i]));
2582   }
2583   PetscFunctionReturn(0);
2584 }
2585 
2586 /*@
2587    TaoSetConvergenceHistory - Sets the array used to hold the convergence history.
2588 
2589    Logically Collective on Tao
2590 
2591    Input Parameters:
2592 +  tao - the Tao solver context
2593 .  obj   - array to hold objective value history
2594 .  resid - array to hold residual history
2595 .  cnorm - array to hold constraint violation history
2596 .  lits - integer array holds the number of linear iterations for each Tao iteration
2597 .  na  - size of obj, resid, and cnorm
2598 -  reset - PetscTrue indicates each new minimization resets the history counter to zero,
2599            else it continues storing new values for new minimizations after the old ones
2600 
2601    Notes:
2602    If set, TAO will fill the given arrays with the indicated
2603    information at each iteration.  If 'obj','resid','cnorm','lits' are
2604    *all* NULL then space (using size na, or 1000 if na is PETSC_DECIDE or
2605    PETSC_DEFAULT) is allocated for the history.
2606    If not all are NULL, then only the non-NULL information categories
2607    will be stored, the others will be ignored.
2608 
2609    Any convergence information after iteration number 'na' will not be stored.
2610 
2611    This routine is useful, e.g., when running a code for purposes
2612    of accurate performance monitoring, when no I/O should be done
2613    during the section of code that is being timed.
2614 
2615    Level: intermediate
2616 
2617 .seealso: `TaoGetConvergenceHistory()`
2618 
2619 @*/
2620 PetscErrorCode TaoSetConvergenceHistory(Tao tao, PetscReal obj[], PetscReal resid[], PetscReal cnorm[], PetscInt lits[], PetscInt na,PetscBool reset)
2621 {
2622   PetscFunctionBegin;
2623   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
2624   if (obj) PetscValidRealPointer(obj,2);
2625   if (resid) PetscValidRealPointer(resid,3);
2626   if (cnorm) PetscValidRealPointer(cnorm,4);
2627   if (lits) PetscValidIntPointer(lits,5);
2628 
2629   if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000;
2630   if (!obj && !resid && !cnorm && !lits) {
2631     PetscCall(PetscCalloc4(na,&obj,na,&resid,na,&cnorm,na,&lits));
2632     tao->hist_malloc = PETSC_TRUE;
2633   }
2634 
2635   tao->hist_obj = obj;
2636   tao->hist_resid = resid;
2637   tao->hist_cnorm = cnorm;
2638   tao->hist_lits = lits;
2639   tao->hist_max   = na;
2640   tao->hist_reset = reset;
2641   tao->hist_len = 0;
2642   PetscFunctionReturn(0);
2643 }
2644 
2645 /*@C
2646    TaoGetConvergenceHistory - Gets the arrays used to hold the convergence history.
2647 
2648    Collective on Tao
2649 
2650    Input Parameter:
2651 .  tao - the Tao context
2652 
2653    Output Parameters:
2654 +  obj   - array used to hold objective value history
2655 .  resid - array used to hold residual history
2656 .  cnorm - array used to hold constraint violation history
2657 .  lits  - integer array used to hold linear solver iteration count
2658 -  nhist  - size of obj, resid, cnorm, and lits
2659 
2660    Notes:
2661     This routine must be preceded by calls to TaoSetConvergenceHistory()
2662     and TaoSolve(), otherwise it returns useless information.
2663 
2664     The calling sequence for this routine in Fortran is
2665 $   call TaoGetConvergenceHistory(Tao tao, PetscInt nhist, PetscErrorCode ierr)
2666 
2667    This routine is useful, e.g., when running a code for purposes
2668    of accurate performance monitoring, when no I/O should be done
2669    during the section of code that is being timed.
2670 
2671    Level: advanced
2672 
2673 .seealso: `TaoSetConvergenceHistory()`
2674 
2675 @*/
2676 PetscErrorCode TaoGetConvergenceHistory(Tao tao, PetscReal **obj, PetscReal **resid, PetscReal **cnorm, PetscInt **lits, PetscInt *nhist)
2677 {
2678   PetscFunctionBegin;
2679   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
2680   if (obj)   *obj   = tao->hist_obj;
2681   if (cnorm) *cnorm = tao->hist_cnorm;
2682   if (resid) *resid = tao->hist_resid;
2683   if (nhist) *nhist = tao->hist_len;
2684   PetscFunctionReturn(0);
2685 }
2686 
2687 /*@
2688    TaoSetApplicationContext - Sets the optional user-defined context for
2689    a solver.
2690 
2691    Logically Collective on Tao
2692 
2693    Input Parameters:
2694 +  tao  - the Tao context
2695 -  usrP - optional user context
2696 
2697    Level: intermediate
2698 
2699 .seealso: `TaoGetApplicationContext()`, `TaoSetApplicationContext()`
2700 @*/
2701 PetscErrorCode  TaoSetApplicationContext(Tao tao,void *usrP)
2702 {
2703   PetscFunctionBegin;
2704   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
2705   tao->user = usrP;
2706   PetscFunctionReturn(0);
2707 }
2708 
2709 /*@
2710    TaoGetApplicationContext - Gets the user-defined context for a
2711    TAO solvers.
2712 
2713    Not Collective
2714 
2715    Input Parameter:
2716 .  tao  - Tao context
2717 
2718    Output Parameter:
2719 .  usrP - user context
2720 
2721    Level: intermediate
2722 
2723 .seealso: `TaoSetApplicationContext()`
2724 @*/
2725 PetscErrorCode  TaoGetApplicationContext(Tao tao,void *usrP)
2726 {
2727   PetscFunctionBegin;
2728   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
2729   PetscValidPointer(usrP,2);
2730   *(void**)usrP = tao->user;
2731   PetscFunctionReturn(0);
2732 }
2733 
2734 /*@
2735    TaoSetGradientNorm - Sets the matrix used to define the inner product that measures the size of the gradient.
2736 
2737    Collective on tao
2738 
2739    Input Parameters:
2740 +  tao  - the Tao context
2741 -  M    - gradient norm
2742 
2743    Level: beginner
2744 
2745 .seealso: `TaoGetGradientNorm()`, `TaoGradientNorm()`
2746 @*/
2747 PetscErrorCode  TaoSetGradientNorm(Tao tao, Mat M)
2748 {
2749   PetscFunctionBegin;
2750   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
2751   PetscValidHeaderSpecific(M,MAT_CLASSID,2);
2752   PetscCall(PetscObjectReference((PetscObject)M));
2753   PetscCall(MatDestroy(&tao->gradient_norm));
2754   PetscCall(VecDestroy(&tao->gradient_norm_tmp));
2755   tao->gradient_norm = M;
2756   PetscCall(MatCreateVecs(M, NULL, &tao->gradient_norm_tmp));
2757   PetscFunctionReturn(0);
2758 }
2759 
2760 /*@
2761    TaoGetGradientNorm - Returns the matrix used to define the inner product for measuring the size of the gradient.
2762 
2763    Not Collective
2764 
2765    Input Parameter:
2766 .  tao  - Tao context
2767 
2768    Output Parameter:
2769 .  M - gradient norm
2770 
2771    Level: beginner
2772 
2773 .seealso: `TaoSetGradientNorm()`, `TaoGradientNorm()`
2774 @*/
2775 PetscErrorCode  TaoGetGradientNorm(Tao tao, Mat *M)
2776 {
2777   PetscFunctionBegin;
2778   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
2779   PetscValidPointer(M,2);
2780   *M = tao->gradient_norm;
2781   PetscFunctionReturn(0);
2782 }
2783 
2784 /*@C
2785    TaoGradientNorm - Compute the norm with respect to the inner product the user has set.
2786 
2787    Collective on tao
2788 
2789    Input Parameters:
2790 +  tao      - the Tao context
2791 .  gradient - the gradient to be computed
2792 -  norm     - the norm type
2793 
2794    Output Parameter:
2795 .  gnorm    - the gradient norm
2796 
2797    Level: developer
2798 
2799 .seealso: `TaoSetGradientNorm()`, `TaoGetGradientNorm()`
2800 @*/
2801 PetscErrorCode  TaoGradientNorm(Tao tao, Vec gradient, NormType type, PetscReal *gnorm)
2802 {
2803   PetscFunctionBegin;
2804   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
2805   PetscValidHeaderSpecific(gradient,VEC_CLASSID,2);
2806   PetscValidLogicalCollectiveEnum(tao,type,3);
2807   PetscValidRealPointer(gnorm,4);
2808   if (tao->gradient_norm) {
2809     PetscScalar gnorms;
2810 
2811     PetscCheck(type == NORM_2,PetscObjectComm((PetscObject)gradient), PETSC_ERR_ARG_WRONG, "Norm type must be NORM_2 if an inner product for the gradient norm is set.");
2812     PetscCall(MatMult(tao->gradient_norm, gradient, tao->gradient_norm_tmp));
2813     PetscCall(VecDot(gradient, tao->gradient_norm_tmp, &gnorms));
2814     *gnorm = PetscRealPart(PetscSqrtScalar(gnorms));
2815   } else {
2816     PetscCall(VecNorm(gradient, type, gnorm));
2817   }
2818   PetscFunctionReturn(0);
2819 }
2820 
2821 /*@C
2822    TaoMonitorDrawCtxCreate - Creates the monitor context for TaoMonitorDrawCtx
2823 
2824    Collective on Tao
2825 
2826    Output Patameter:
2827 .    ctx - the monitor context
2828 
2829    Options Database:
2830 .   -tao_draw_solution_initial - show initial guess as well as current solution
2831 
2832    Level: intermediate
2833 
2834 .seealso: `TaoMonitorSet()`, `TaoMonitorDefault()`, `VecView()`, `TaoMonitorDrawCtx()`
2835 @*/
2836 PetscErrorCode  TaoMonitorDrawCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TaoMonitorDrawCtx *ctx)
2837 {
2838   PetscFunctionBegin;
2839   PetscCall(PetscNew(ctx));
2840   PetscCall(PetscViewerDrawOpen(comm,host,label,x,y,m,n,&(*ctx)->viewer));
2841   PetscCall(PetscViewerSetFromOptions((*ctx)->viewer));
2842   (*ctx)->howoften = howoften;
2843   PetscFunctionReturn(0);
2844 }
2845 
2846 /*@C
2847    TaoMonitorDrawCtxDestroy - Destroys the monitor context for TaoMonitorDrawSolution()
2848 
2849    Collective on Tao
2850 
2851    Input Parameters:
2852 .    ctx - the monitor context
2853 
2854    Level: intermediate
2855 
2856 .seealso: `TaoMonitorSet()`, `TaoMonitorDefault()`, `VecView()`, `TaoMonitorDrawSolution()`
2857 @*/
2858 PetscErrorCode  TaoMonitorDrawCtxDestroy(TaoMonitorDrawCtx *ictx)
2859 {
2860   PetscFunctionBegin;
2861   PetscCall(PetscViewerDestroy(&(*ictx)->viewer));
2862   PetscCall(PetscFree(*ictx));
2863   PetscFunctionReturn(0);
2864 }
2865