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