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