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