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