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