Actual source code: taosolver.c
1: #include <petsc/private/taoimpl.h>
2: #include <petsc/private/snesimpl.h>
4: PetscBool TaoRegisterAllCalled = PETSC_FALSE;
5: PetscFunctionList TaoList = NULL;
7: PetscClassId TAO_CLASSID;
9: PetscLogEvent TAO_Solve;
10: PetscLogEvent TAO_ObjectiveEval;
11: PetscLogEvent TAO_GradientEval;
12: PetscLogEvent TAO_ObjGradEval;
13: PetscLogEvent TAO_HessianEval;
14: PetscLogEvent TAO_JacobianEval;
15: PetscLogEvent TAO_ConstraintsEval;
17: const char *TaoSubSetTypes[] = {"subvec", "mask", "matrixfree", "TaoSubSetType", "TAO_SUBSET_", NULL};
19: struct _n_TaoMonitorDrawCtx {
20: PetscViewer viewer;
21: PetscInt howoften; /* when > 0 uses iteration % howoften, when negative only final solution plotted */
22: };
24: static PetscErrorCode KSPPreSolve_TAOEW_Private(KSP ksp, Vec b, Vec x, Tao tao)
25: {
26: SNES snes_ewdummy = tao->snes_ewdummy;
28: if (!snes_ewdummy) return 0;
29: /* populate snes_ewdummy struct values used in KSPPreSolve_SNESEW */
30: snes_ewdummy->vec_func = b;
31: snes_ewdummy->rtol = tao->gttol;
32: snes_ewdummy->iter = tao->niter;
33: VecNorm(b, NORM_2, &snes_ewdummy->norm);
34: KSPPreSolve_SNESEW(ksp, b, x, snes_ewdummy);
35: snes_ewdummy->vec_func = NULL;
36: return 0;
37: }
39: static PetscErrorCode KSPPostSolve_TAOEW_Private(KSP ksp, Vec b, Vec x, Tao tao)
40: {
41: SNES snes_ewdummy = tao->snes_ewdummy;
43: if (!snes_ewdummy) return 0;
44: KSPPostSolve_SNESEW(ksp, b, x, snes_ewdummy);
45: return 0;
46: }
48: static PetscErrorCode TaoSetUpEW_Private(Tao tao)
49: {
50: SNESKSPEW *kctx;
51: const char *ewprefix;
53: if (!tao->ksp) return 0;
54: if (tao->ksp_ewconv) {
55: if (!tao->snes_ewdummy) SNESCreate(PetscObjectComm((PetscObject)tao), &tao->snes_ewdummy);
56: tao->snes_ewdummy->ksp_ewconv = PETSC_TRUE;
57: KSPSetPreSolve(tao->ksp, (PetscErrorCode(*)(KSP, Vec, Vec, void *))KSPPreSolve_TAOEW_Private, tao);
58: KSPSetPostSolve(tao->ksp, (PetscErrorCode(*)(KSP, Vec, Vec, void *))KSPPostSolve_TAOEW_Private, tao);
60: KSPGetOptionsPrefix(tao->ksp, &ewprefix);
61: kctx = (SNESKSPEW *)tao->snes_ewdummy->kspconvctx;
62: SNESEWSetFromOptions_Private(kctx, PetscObjectComm((PetscObject)tao), ewprefix);
63: } else SNESDestroy(&tao->snes_ewdummy);
64: return 0;
65: }
67: /*@
68: TaoCreate - Creates a Tao solver
70: Collective
72: Input Parameter:
73: . comm - MPI communicator
75: Output Parameter:
76: . newtao - the new Tao context
78: Available methods include:
79: + `TAONLS` - nls Newton's method with line search for unconstrained minimization
80: . `TAONTR` - ntr Newton's method with trust region for unconstrained minimization
81: . `TAONTL` - ntl Newton's method with trust region, line search for unconstrained minimization
82: . `TAOLMVM` - lmvm Limited memory variable metric method for unconstrained minimization
83: . `TAOCG` - cg Nonlinear conjugate gradient method for unconstrained minimization
84: . `TAONM` - nm Nelder-Mead algorithm for derivate-free unconstrained minimization
85: . `TAOTRON` - tron Newton Trust Region method for bound constrained minimization
86: . `TAOGPCG` - gpcg Newton Trust Region method for quadratic bound constrained minimization
87: . `TAOBLMVM` - blmvm Limited memory variable metric method for bound constrained minimization
88: . `TAOLCL` - lcl Linearly constrained Lagrangian method for pde-constrained minimization
89: - `TAOPOUNDERS` - pounders Model-based algorithm for nonlinear least squares
91: Options Database Keys:
92: . -tao_type - select which method Tao should use
94: Level: beginner
96: .seealso: `Tao`, `TaoSolve()`, `TaoDestroy()`, `TAOSetFromOptions()`, `TAOSetType()`
97: @*/
98: PetscErrorCode TaoCreate(MPI_Comm comm, Tao *newtao)
99: {
100: Tao tao;
103: TaoInitializePackage();
104: TaoLineSearchInitializePackage();
105: PetscHeaderCreate(tao, TAO_CLASSID, "Tao", "Optimization solver", "Tao", comm, TaoDestroy, TaoView);
107: /* Set non-NULL defaults */
108: tao->ops->convergencetest = TaoDefaultConvergenceTest;
110: tao->max_it = 10000;
111: tao->max_funcs = -1;
112: #if defined(PETSC_USE_REAL_SINGLE)
113: tao->gatol = 1e-5;
114: tao->grtol = 1e-5;
115: tao->crtol = 1e-5;
116: tao->catol = 1e-5;
117: #else
118: tao->gatol = 1e-8;
119: tao->grtol = 1e-8;
120: tao->crtol = 1e-8;
121: tao->catol = 1e-8;
122: #endif
123: tao->gttol = 0.0;
124: tao->steptol = 0.0;
125: tao->trust0 = PETSC_INFINITY;
126: tao->fmin = PETSC_NINFINITY;
128: tao->hist_reset = PETSC_TRUE;
130: TaoResetStatistics(tao);
131: *newtao = tao;
132: return 0;
133: }
135: /*@
136: TaoSolve - Solves an optimization problem min F(x) s.t. l <= x <= u
138: Collective on tao
140: Input Parameters:
141: . tao - the Tao context
143: Notes:
144: The user must set up the Tao with calls to `TaoSetSolution()`, `TaoSetObjective()`, `TaoSetGradient()`, and (if using 2nd order method) `TaoSetHessian()`.
146: You should call `TaoGetConvergedReason()` or run with -tao_converged_reason to determine if the optimization algorithm actually succeeded or
147: why it failed.
149: Level: beginner
151: .seealso: `Tao`, `TaoCreate()`, `TaoSetObjective()`, `TaoSetGradient()`, `TaoSetHessian()`, `TaoGetConvergedReason()`, `TaoSetUp()`
152: @*/
153: PetscErrorCode TaoSolve(Tao tao)
154: {
155: static PetscBool set = PETSC_FALSE;
158: PetscCall(PetscCitationsRegister("@TechReport{tao-user-ref,\n"
159: "title = {Toolkit for Advanced Optimization (TAO) Users Manual},\n"
160: "author = {Todd Munson and Jason Sarich and Stefan Wild and Steve Benson and Lois Curfman McInnes},\n"
161: "Institution = {Argonne National Laboratory},\n"
162: "Year = 2014,\n"
163: "Number = {ANL/MCS-TM-322 - Revision 3.5},\n"
164: "url = {https://www.mcs.anl.gov/research/projects/tao/}\n}\n",
165: &set));
166: tao->header_printed = PETSC_FALSE;
167: TaoSetUp(tao);
168: TaoResetStatistics(tao);
169: if (tao->linesearch) TaoLineSearchReset(tao->linesearch);
171: PetscLogEventBegin(TAO_Solve, tao, 0, 0, 0);
172: PetscTryTypeMethod(tao, solve);
173: PetscLogEventEnd(TAO_Solve, tao, 0, 0, 0);
175: VecViewFromOptions(tao->solution, (PetscObject)tao, "-tao_view_solution");
177: tao->ntotalits += tao->niter;
178: TaoViewFromOptions(tao, NULL, "-tao_view");
180: if (tao->printreason) {
181: if (tao->reason > 0) {
182: PetscPrintf(((PetscObject)tao)->comm, "TAO solve converged due to %s iterations %" PetscInt_FMT "\n", TaoConvergedReasons[tao->reason], tao->niter);
183: } else {
184: PetscPrintf(((PetscObject)tao)->comm, "TAO solve did not converge due to %s iteration %" PetscInt_FMT "\n", TaoConvergedReasons[tao->reason], tao->niter);
185: }
186: }
187: return 0;
188: }
190: /*@
191: TaoSetUp - Sets up the internal data structures for the later use
192: of a Tao solver
194: Collective on tao
196: Input Parameters:
197: . tao - the Tao context
199: Notes:
200: The user will not need to explicitly call `TaoSetUp()`, as it will
201: automatically be called in `TaoSolve()`. However, if the user
202: desires to call it explicitly, it should come after `TaoCreate()`
203: and any TaoSetSomething() routines, but before `TaoSolve()`.
205: Level: advanced
207: .seealso: `Tao`, `TaoCreate()`, `TaoSolve()`
208: @*/
209: PetscErrorCode TaoSetUp(Tao tao)
210: {
212: if (tao->setupcalled) return 0;
213: TaoSetUpEW_Private(tao);
215: PetscTryTypeMethod(tao, setup);
216: tao->setupcalled = PETSC_TRUE;
217: return 0;
218: }
220: /*@C
221: TaoDestroy - Destroys the Tao context that was created with `TaoCreate()`
223: Collective on tao
225: Input Parameter:
226: . tao - the Tao context
228: Level: beginner
230: .seealso: `Tao`, `TaoCreate()`, `TaoSolve()`
231: @*/
232: PetscErrorCode TaoDestroy(Tao *tao)
233: {
234: if (!*tao) return 0;
236: if (--((PetscObject)*tao)->refct > 0) {
237: *tao = NULL;
238: return 0;
239: }
241: if ((*tao)->ops->destroy) (*((*tao))->ops->destroy)(*tao);
242: KSPDestroy(&(*tao)->ksp);
243: SNESDestroy(&(*tao)->snes_ewdummy);
244: TaoLineSearchDestroy(&(*tao)->linesearch);
246: if ((*tao)->ops->convergencedestroy) {
247: (*(*tao)->ops->convergencedestroy)((*tao)->cnvP);
248: if ((*tao)->jacobian_state_inv) MatDestroy(&(*tao)->jacobian_state_inv);
249: }
250: VecDestroy(&(*tao)->solution);
251: VecDestroy(&(*tao)->gradient);
252: VecDestroy(&(*tao)->ls_res);
254: if ((*tao)->gradient_norm) {
255: PetscObjectDereference((PetscObject)(*tao)->gradient_norm);
256: VecDestroy(&(*tao)->gradient_norm_tmp);
257: }
259: VecDestroy(&(*tao)->XL);
260: VecDestroy(&(*tao)->XU);
261: VecDestroy(&(*tao)->IL);
262: VecDestroy(&(*tao)->IU);
263: VecDestroy(&(*tao)->DE);
264: VecDestroy(&(*tao)->DI);
265: VecDestroy(&(*tao)->constraints);
266: VecDestroy(&(*tao)->constraints_equality);
267: VecDestroy(&(*tao)->constraints_inequality);
268: VecDestroy(&(*tao)->stepdirection);
269: MatDestroy(&(*tao)->hessian_pre);
270: MatDestroy(&(*tao)->hessian);
271: MatDestroy(&(*tao)->ls_jac);
272: MatDestroy(&(*tao)->ls_jac_pre);
273: MatDestroy(&(*tao)->jacobian_pre);
274: MatDestroy(&(*tao)->jacobian);
275: MatDestroy(&(*tao)->jacobian_state_pre);
276: MatDestroy(&(*tao)->jacobian_state);
277: MatDestroy(&(*tao)->jacobian_state_inv);
278: MatDestroy(&(*tao)->jacobian_design);
279: MatDestroy(&(*tao)->jacobian_equality);
280: MatDestroy(&(*tao)->jacobian_equality_pre);
281: MatDestroy(&(*tao)->jacobian_inequality);
282: MatDestroy(&(*tao)->jacobian_inequality_pre);
283: ISDestroy(&(*tao)->state_is);
284: ISDestroy(&(*tao)->design_is);
285: VecDestroy(&(*tao)->res_weights_v);
286: TaoCancelMonitors(*tao);
287: if ((*tao)->hist_malloc) PetscFree4((*tao)->hist_obj, (*tao)->hist_resid, (*tao)->hist_cnorm, (*tao)->hist_lits);
288: if ((*tao)->res_weights_n) {
289: PetscFree((*tao)->res_weights_rows);
290: PetscFree((*tao)->res_weights_cols);
291: PetscFree((*tao)->res_weights_w);
292: }
293: PetscHeaderDestroy(tao);
294: return 0;
295: }
297: /*@
298: TaoKSPSetUseEW - Sets `SNES` use Eisenstat-Walker method for
299: computing relative tolerance for linear solvers.
301: Logically Collective on tao
303: Input Parameters:
304: + tao - Tao context
305: - flag - `PETSC_TRUE` or `PETSC_FALSE`
307: Notes:
308: See `SNESKSPSetUseEW()` for customization details.
310: Level: advanced
312: Reference:
313: S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
314: inexact Newton method", SISC 17 (1), pp.16-32, 1996.
316: .seealso: `Tao`, `SNESKSPSetUseEW()`
317: @*/
318: PetscErrorCode TaoKSPSetUseEW(Tao tao, PetscBool flag)
319: {
322: tao->ksp_ewconv = flag;
323: return 0;
324: }
326: /*@
327: TaoSetFromOptions - Sets various Tao parameters from user
328: options.
330: Collective on tao
332: Input Parameter:
333: . tao - the Tao solver context
335: options Database Keys:
336: + -tao_type <type> - The algorithm that Tao uses (lmvm, nls, etc.)
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_ls_residual - prints least-squares residual vector at each iteration
350: . -tao_view_stepdirection - 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_fd_hessian - use hessian computed with finite differences
357: . -tao_mf_hessian - use matrix-free hessian computed with finite differences
358: . -tao_cancelmonitors - cancels all monitors (except those set with command line)
359: . -tao_view - prints information about the Tao after solving
360: - -tao_converged_reason - prints the reason Tao stopped iterating
362: Notes:
363: To see all options, run your program with the -help option or consult the
364: user's manual. Should be called after `TaoCreate()` but before `TaoSolve()`
366: Level: beginner
368: .seealso: `Tao`, `TaoCreate()`, `TaoSolve()`
369: @*/
370: PetscErrorCode TaoSetFromOptions(Tao tao)
371: {
372: TaoType default_type = TAOLMVM;
373: char type[256], monfilename[PETSC_MAX_PATH_LEN];
374: PetscViewer monviewer;
375: PetscBool flg;
376: MPI_Comm comm;
379: PetscObjectGetComm((PetscObject)tao, &comm);
381: /* So no warnings are given about unused options */
382: PetscOptionsHasName(((PetscObject)tao)->options, ((PetscObject)tao)->prefix, "-tao_ls_type", &flg);
384: PetscObjectOptionsBegin((PetscObject)tao);
385: {
386: if (((PetscObject)tao)->type_name) default_type = ((PetscObject)tao)->type_name;
387: /* Check for type from options */
388: PetscOptionsFList("-tao_type", "Tao Solver type", "TaoSetType", TaoList, default_type, type, 256, &flg);
389: if (flg) {
390: TaoSetType(tao, type);
391: } else if (!((PetscObject)tao)->type_name) {
392: TaoSetType(tao, default_type);
393: }
395: PetscOptionsReal("-tao_catol", "Stop if constraints violations within", "TaoSetConstraintTolerances", tao->catol, &tao->catol, &flg);
396: if (flg) tao->catol_changed = PETSC_TRUE;
397: PetscOptionsReal("-tao_crtol", "Stop if relative constraint violations within", "TaoSetConstraintTolerances", tao->crtol, &tao->crtol, &flg);
398: if (flg) tao->crtol_changed = PETSC_TRUE;
399: PetscOptionsReal("-tao_gatol", "Stop if norm of gradient less than", "TaoSetTolerances", tao->gatol, &tao->gatol, &flg);
400: if (flg) tao->gatol_changed = PETSC_TRUE;
401: PetscOptionsReal("-tao_grtol", "Stop if norm of gradient divided by the function value is less than", "TaoSetTolerances", tao->grtol, &tao->grtol, &flg);
402: if (flg) tao->grtol_changed = PETSC_TRUE;
403: 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);
404: if (flg) tao->gttol_changed = PETSC_TRUE;
405: PetscOptionsInt("-tao_max_it", "Stop if iteration number exceeds", "TaoSetMaximumIterations", tao->max_it, &tao->max_it, &flg);
406: if (flg) tao->max_it_changed = PETSC_TRUE;
407: PetscOptionsInt("-tao_max_funcs", "Stop if number of function evaluations exceeds", "TaoSetMaximumFunctionEvaluations", tao->max_funcs, &tao->max_funcs, &flg);
408: if (flg) tao->max_funcs_changed = PETSC_TRUE;
409: PetscOptionsReal("-tao_fmin", "Stop if function less than", "TaoSetFunctionLowerBound", tao->fmin, &tao->fmin, &flg);
410: if (flg) tao->fmin_changed = PETSC_TRUE;
411: PetscOptionsReal("-tao_steptol", "Stop if step size or trust region radius less than", "", tao->steptol, &tao->steptol, &flg);
412: if (flg) tao->steptol_changed = PETSC_TRUE;
413: PetscOptionsReal("-tao_trust0", "Initial trust region radius", "TaoSetTrustRegionRadius", tao->trust0, &tao->trust0, &flg);
414: if (flg) tao->trust0_changed = PETSC_TRUE;
415: PetscOptionsString("-tao_view_solution", "view solution vector after each evaluation", "TaoSetMonitor", "stdout", monfilename, sizeof(monfilename), &flg);
416: if (flg) {
417: PetscViewerASCIIOpen(comm, monfilename, &monviewer);
418: TaoSetMonitor(tao, TaoSolutionMonitor, monviewer, (PetscErrorCode(*)(void **))PetscViewerDestroy);
419: }
421: PetscOptionsBool("-tao_converged_reason", "Print reason for Tao converged", "TaoSolve", tao->printreason, &tao->printreason, NULL);
422: PetscOptionsString("-tao_view_gradient", "view gradient vector after each evaluation", "TaoSetMonitor", "stdout", monfilename, sizeof(monfilename), &flg);
423: if (flg) {
424: PetscViewerASCIIOpen(comm, monfilename, &monviewer);
425: TaoSetMonitor(tao, TaoGradientMonitor, monviewer, (PetscErrorCode(*)(void **))PetscViewerDestroy);
426: }
428: PetscOptionsString("-tao_view_stepdirection", "view step direction vector after each iteration", "TaoSetMonitor", "stdout", monfilename, sizeof(monfilename), &flg);
429: if (flg) {
430: PetscViewerASCIIOpen(comm, monfilename, &monviewer);
431: TaoSetMonitor(tao, TaoStepDirectionMonitor, monviewer, (PetscErrorCode(*)(void **))PetscViewerDestroy);
432: }
434: PetscOptionsString("-tao_view_residual", "view least-squares residual vector after each evaluation", "TaoSetMonitor", "stdout", monfilename, sizeof(monfilename), &flg);
435: if (flg) {
436: PetscViewerASCIIOpen(comm, monfilename, &monviewer);
437: TaoSetMonitor(tao, TaoResidualMonitor, monviewer, (PetscErrorCode(*)(void **))PetscViewerDestroy);
438: }
440: PetscOptionsString("-tao_monitor", "Use the default convergence monitor", "TaoSetMonitor", "stdout", monfilename, sizeof(monfilename), &flg);
441: if (flg) {
442: PetscViewerASCIIOpen(comm, monfilename, &monviewer);
443: TaoSetMonitor(tao, TaoMonitorDefault, monviewer, (PetscErrorCode(*)(void **))PetscViewerDestroy);
444: }
446: PetscOptionsString("-tao_gmonitor", "Use the convergence monitor with extra globalization info", "TaoSetMonitor", "stdout", monfilename, sizeof(monfilename), &flg);
447: if (flg) {
448: PetscViewerASCIIOpen(comm, monfilename, &monviewer);
449: TaoSetMonitor(tao, TaoDefaultGMonitor, monviewer, (PetscErrorCode(*)(void **))PetscViewerDestroy);
450: }
452: PetscOptionsString("-tao_smonitor", "Use the short convergence monitor", "TaoSetMonitor", "stdout", monfilename, sizeof(monfilename), &flg);
453: if (flg) {
454: PetscViewerASCIIOpen(comm, monfilename, &monviewer);
455: TaoSetMonitor(tao, TaoDefaultSMonitor, monviewer, (PetscErrorCode(*)(void **))PetscViewerDestroy);
456: }
458: PetscOptionsString("-tao_cmonitor", "Use the default convergence monitor with constraint norm", "TaoSetMonitor", "stdout", monfilename, sizeof(monfilename), &flg);
459: if (flg) {
460: PetscViewerASCIIOpen(comm, monfilename, &monviewer);
461: TaoSetMonitor(tao, TaoDefaultCMonitor, monviewer, (PetscErrorCode(*)(void **))PetscViewerDestroy);
462: }
464: flg = PETSC_FALSE;
465: PetscOptionsBool("-tao_cancelmonitors", "cancel all monitors and call any registered destroy routines", "TaoCancelMonitors", flg, &flg, NULL);
466: if (flg) TaoCancelMonitors(tao);
468: flg = PETSC_FALSE;
469: PetscOptionsBool("-tao_draw_solution", "Plot solution vector at each iteration", "TaoSetMonitor", flg, &flg, NULL);
470: if (flg) {
471: TaoMonitorDrawCtx drawctx;
472: PetscInt howoften = 1;
473: TaoMonitorDrawCtxCreate(PetscObjectComm((PetscObject)tao), NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 300, 300, howoften, &drawctx);
474: TaoSetMonitor(tao, TaoDrawSolutionMonitor, drawctx, (PetscErrorCode(*)(void **))TaoMonitorDrawCtxDestroy);
475: }
477: flg = PETSC_FALSE;
478: PetscOptionsBool("-tao_draw_step", "plots step direction at each iteration", "TaoSetMonitor", flg, &flg, NULL);
479: if (flg) TaoSetMonitor(tao, TaoDrawStepMonitor, NULL, NULL);
481: flg = PETSC_FALSE;
482: PetscOptionsBool("-tao_draw_gradient", "plots gradient at each iteration", "TaoSetMonitor", flg, &flg, NULL);
483: if (flg) {
484: TaoMonitorDrawCtx drawctx;
485: PetscInt howoften = 1;
486: TaoMonitorDrawCtxCreate(PetscObjectComm((PetscObject)tao), NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 300, 300, howoften, &drawctx);
487: TaoSetMonitor(tao, TaoDrawGradientMonitor, drawctx, (PetscErrorCode(*)(void **))TaoMonitorDrawCtxDestroy);
488: }
489: flg = PETSC_FALSE;
490: PetscOptionsBool("-tao_fd_gradient", "compute gradient using finite differences", "TaoDefaultComputeGradient", flg, &flg, NULL);
491: if (flg) TaoSetGradient(tao, NULL, TaoDefaultComputeGradient, NULL);
492: flg = PETSC_FALSE;
493: PetscOptionsBool("-tao_fd_hessian", "compute hessian using finite differences", "TaoDefaultComputeHessian", flg, &flg, NULL);
494: if (flg) {
495: Mat H;
497: MatCreate(PetscObjectComm((PetscObject)tao), &H);
498: MatSetType(H, MATAIJ);
499: TaoSetHessian(tao, H, H, TaoDefaultComputeHessian, NULL);
500: MatDestroy(&H);
501: }
502: flg = PETSC_FALSE;
503: PetscOptionsBool("-tao_mf_hessian", "compute matrix-free hessian using finite differences", "TaoDefaultComputeHessianMFFD", flg, &flg, NULL);
504: if (flg) {
505: Mat H;
507: MatCreate(PetscObjectComm((PetscObject)tao), &H);
508: TaoSetHessian(tao, H, H, TaoDefaultComputeHessianMFFD, NULL);
509: MatDestroy(&H);
510: }
511: flg = PETSC_FALSE;
512: PetscOptionsBool("-tao_recycle_history", "enable recycling/re-using information from the previous TaoSolve() call for some algorithms", "TaoSetRecycleHistory", flg, &flg, NULL);
513: if (flg) TaoSetRecycleHistory(tao, PETSC_TRUE);
514: PetscOptionsEnum("-tao_subset_type", "subset type", "", TaoSubSetTypes, (PetscEnum)tao->subset_type, (PetscEnum *)&tao->subset_type, NULL);
516: if (tao->ksp) {
517: PetscOptionsBool("-tao_ksp_ew", "Use Eisentat-Walker linear system convergence test", "TaoKSPSetUseEW", tao->ksp_ewconv, &tao->ksp_ewconv, NULL);
518: TaoKSPSetUseEW(tao, tao->ksp_ewconv);
519: }
521: if (tao->linesearch) TaoLineSearchSetFromOptions(tao->linesearch);
523: PetscTryTypeMethod(tao, setfromoptions, PetscOptionsObject);
524: }
525: PetscOptionsEnd();
526: return 0;
527: }
529: /*@C
530: TaoViewFromOptions - View a Tao options from the options database
532: Collective on tao
534: Input Parameters:
535: + A - the Tao context
536: . obj - Optional object
537: - name - command line option
539: Level: intermediate
540: .seealso: `Tao`, `TaoView`, `PetscObjectViewFromOptions()`, `TaoCreate()`
541: @*/
542: PetscErrorCode TaoViewFromOptions(Tao A, PetscObject obj, const char name[])
543: {
545: PetscObjectViewFromOptions((PetscObject)A, obj, name);
546: return 0;
547: }
549: /*@C
550: TaoView - Prints information about the Tao object
552: Collective on tao
554: InputParameters:
555: + tao - the Tao context
556: - viewer - visualization context
558: Options Database Key:
559: . -tao_view - Calls `TaoView()` at the end of `TaoSolve()`
561: Notes:
562: The available visualization contexts include
563: + `PETSC_VIEWER_STDOUT_SELF` - standard output (default)
564: - `PETSC_VIEWER_STDOUT_WORLD` - synchronized standard
565: output where only the first processor opens
566: the file. All other processors send their
567: data to the first processor to print.
569: Level: beginner
571: .seealso: `PetscViewerASCIIOpen()`
572: @*/
573: PetscErrorCode TaoView(Tao tao, PetscViewer viewer)
574: {
575: PetscBool isascii, isstring;
576: TaoType type;
579: if (!viewer) PetscViewerASCIIGetStdout(((PetscObject)tao)->comm, &viewer);
583: PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii);
584: PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSTRING, &isstring);
585: if (isascii) {
586: PetscObjectPrintClassNamePrefixType((PetscObject)tao, viewer);
588: if (tao->ops->view) {
589: PetscViewerASCIIPushTab(viewer);
590: PetscUseTypeMethod(tao, view, viewer);
591: PetscViewerASCIIPopTab(viewer);
592: }
593: if (tao->linesearch) {
594: PetscViewerASCIIPushTab(viewer);
595: TaoLineSearchView(tao->linesearch, viewer);
596: PetscViewerASCIIPopTab(viewer);
597: }
598: if (tao->ksp) {
599: PetscViewerASCIIPushTab(viewer);
600: KSPView(tao->ksp, viewer);
601: PetscViewerASCIIPrintf(viewer, "total KSP iterations: %" PetscInt_FMT "\n", tao->ksp_tot_its);
602: PetscViewerASCIIPopTab(viewer);
603: }
605: PetscViewerASCIIPushTab(viewer);
607: if (tao->XL || tao->XU) PetscViewerASCIIPrintf(viewer, "Active Set subset type: %s\n", TaoSubSetTypes[tao->subset_type]);
609: PetscViewerASCIIPrintf(viewer, "convergence tolerances: gatol=%g,", (double)tao->gatol);
610: PetscViewerASCIIPrintf(viewer, " steptol=%g,", (double)tao->steptol);
611: PetscViewerASCIIPrintf(viewer, " gttol=%g\n", (double)tao->gttol);
612: PetscViewerASCIIPrintf(viewer, "Residual in Function/Gradient:=%g\n", (double)tao->residual);
614: if (tao->constrained) {
615: PetscViewerASCIIPrintf(viewer, "convergence tolerances:");
616: PetscViewerASCIIPrintf(viewer, " catol=%g,", (double)tao->catol);
617: PetscViewerASCIIPrintf(viewer, " crtol=%g\n", (double)tao->crtol);
618: PetscViewerASCIIPrintf(viewer, "Residual in Constraints:=%g\n", (double)tao->cnorm);
619: }
621: if (tao->trust < tao->steptol) {
622: PetscViewerASCIIPrintf(viewer, "convergence tolerances: steptol=%g\n", (double)tao->steptol);
623: PetscViewerASCIIPrintf(viewer, "Final trust region radius:=%g\n", (double)tao->trust);
624: }
626: if (tao->fmin > -1.e25) PetscViewerASCIIPrintf(viewer, "convergence tolerances: function minimum=%g\n", (double)tao->fmin);
627: PetscViewerASCIIPrintf(viewer, "Objective value=%g\n", (double)tao->fc);
629: PetscViewerASCIIPrintf(viewer, "total number of iterations=%" PetscInt_FMT ", ", tao->niter);
630: PetscViewerASCIIPrintf(viewer, " (max: %" PetscInt_FMT ")\n", tao->max_it);
632: if (tao->nfuncs > 0) {
633: PetscViewerASCIIPrintf(viewer, "total number of function evaluations=%" PetscInt_FMT ",", tao->nfuncs);
634: PetscViewerASCIIPrintf(viewer, " max: %" PetscInt_FMT "\n", tao->max_funcs);
635: }
636: if (tao->ngrads > 0) {
637: PetscViewerASCIIPrintf(viewer, "total number of gradient evaluations=%" PetscInt_FMT ",", tao->ngrads);
638: PetscViewerASCIIPrintf(viewer, " max: %" PetscInt_FMT "\n", tao->max_funcs);
639: }
640: if (tao->nfuncgrads > 0) {
641: PetscViewerASCIIPrintf(viewer, "total number of function/gradient evaluations=%" PetscInt_FMT ",", tao->nfuncgrads);
642: PetscViewerASCIIPrintf(viewer, " (max: %" PetscInt_FMT ")\n", tao->max_funcs);
643: }
644: if (tao->nhess > 0) PetscViewerASCIIPrintf(viewer, "total number of Hessian evaluations=%" PetscInt_FMT "\n", tao->nhess);
645: if (tao->nconstraints > 0) PetscViewerASCIIPrintf(viewer, "total number of constraint function evaluations=%" PetscInt_FMT "\n", tao->nconstraints);
646: if (tao->njac > 0) PetscViewerASCIIPrintf(viewer, "total number of Jacobian evaluations=%" PetscInt_FMT "\n", tao->njac);
648: if (tao->reason > 0) {
649: PetscViewerASCIIPrintf(viewer, "Solution converged: ");
650: switch (tao->reason) {
651: case TAO_CONVERGED_GATOL:
652: PetscViewerASCIIPrintf(viewer, " ||g(X)|| <= gatol\n");
653: break;
654: case TAO_CONVERGED_GRTOL:
655: PetscViewerASCIIPrintf(viewer, " ||g(X)||/|f(X)| <= grtol\n");
656: break;
657: case TAO_CONVERGED_GTTOL:
658: PetscViewerASCIIPrintf(viewer, " ||g(X)||/||g(X0)|| <= gttol\n");
659: break;
660: case TAO_CONVERGED_STEPTOL:
661: PetscViewerASCIIPrintf(viewer, " Steptol -- step size small\n");
662: break;
663: case TAO_CONVERGED_MINF:
664: PetscViewerASCIIPrintf(viewer, " Minf -- f < fmin\n");
665: break;
666: case TAO_CONVERGED_USER:
667: PetscViewerASCIIPrintf(viewer, " User Terminated\n");
668: break;
669: default:
670: PetscViewerASCIIPrintf(viewer, "\n");
671: break;
672: }
673: } else {
674: PetscViewerASCIIPrintf(viewer, "Solver terminated: %d", tao->reason);
675: switch (tao->reason) {
676: case TAO_DIVERGED_MAXITS:
677: PetscViewerASCIIPrintf(viewer, " Maximum Iterations\n");
678: break;
679: case TAO_DIVERGED_NAN:
680: PetscViewerASCIIPrintf(viewer, " NAN or Inf encountered\n");
681: break;
682: case TAO_DIVERGED_MAXFCN:
683: PetscViewerASCIIPrintf(viewer, " Maximum Function Evaluations\n");
684: break;
685: case TAO_DIVERGED_LS_FAILURE:
686: PetscViewerASCIIPrintf(viewer, " Line Search Failure\n");
687: break;
688: case TAO_DIVERGED_TR_REDUCTION:
689: PetscViewerASCIIPrintf(viewer, " Trust Region too small\n");
690: break;
691: case TAO_DIVERGED_USER:
692: PetscViewerASCIIPrintf(viewer, " User Terminated\n");
693: break;
694: default:
695: PetscViewerASCIIPrintf(viewer, "\n");
696: break;
697: }
698: }
699: PetscViewerASCIIPopTab(viewer);
700: } else if (isstring) {
701: TaoGetType(tao, &type);
702: PetscViewerStringSPrintf(viewer, " %-3.3s", type);
703: }
704: return 0;
705: }
707: /*@
708: TaoSetRecycleHistory - Sets the boolean flag to enable/disable re-using
709: iterate information from the previous `TaoSolve()`. This feature is disabled by
710: default.
712: For conjugate gradient methods (`TAOBNCG`), this re-uses the latest search direction
713: from the previous `TaoSolve()` call when computing the first search direction in a
714: new solution. By default, CG methods set the first search direction to the
715: negative gradient.
717: For quasi-Newton family of methods (`TAOBQNLS`, `TAOBQNKLS`, `TAOBQNKTR`, `TAOBQNKTL`), this re-uses
718: the accumulated quasi-Newton Hessian approximation from the previous `TaoSolve()`
719: call. By default, QN family of methods reset the initial Hessian approximation to
720: the identity matrix.
722: For any other algorithm, this setting has no effect.
724: Logically collective on tao
726: Input Parameters:
727: + tao - the Tao context
728: - recycle - boolean flag
730: Options Database Keys:
731: . -tao_recycle_history <true,false> - reuse the history
733: Level: intermediate
735: .seealso: `TaoGetRecycleHistory()`, `TAOBNCG`, `TAOBQNLS`, `TAOBQNKLS`, `TAOBQNKTR`, `TAOBQNKTL`
737: @*/
738: PetscErrorCode TaoSetRecycleHistory(Tao tao, PetscBool recycle)
739: {
742: tao->recycle = recycle;
743: return 0;
744: }
746: /*@
747: TaoGetRecycleHistory - Retrieve the boolean flag for re-using iterate information
748: from the previous `TaoSolve()`. This feature is disabled by default.
750: Logically collective on tao
752: Input Parameters:
753: . tao - the Tao context
755: Output Parameters:
756: . recycle - boolean flag
758: Level: intermediate
760: .seealso: `TaoSetRecycleHistory()`, `TAOBNCG`, `TAOBQNLS`, `TAOBQNKLS`, `TAOBQNKTR`, `TAOBQNKTL`
762: @*/
763: PetscErrorCode TaoGetRecycleHistory(Tao tao, PetscBool *recycle)
764: {
767: *recycle = tao->recycle;
768: return 0;
769: }
771: /*@
772: TaoSetTolerances - Sets parameters used in Tao convergence tests
774: Logically collective on tao
776: Input Parameters:
777: + tao - the Tao context
778: . gatol - stop if norm of gradient is less than this
779: . grtol - stop if relative norm of gradient is less than this
780: - gttol - stop if norm of gradient is reduced by this factor
782: Options Database Keys:
783: + -tao_gatol <gatol> - Sets gatol
784: . -tao_grtol <grtol> - Sets grtol
785: - -tao_gttol <gttol> - Sets gttol
787: Stopping Criteria:
788: $ ||g(X)|| <= gatol
789: $ ||g(X)|| / |f(X)| <= grtol
790: $ ||g(X)|| / ||g(X0)|| <= gttol
792: Notes:
793: Use PETSC_DEFAULT to leave one or more tolerances unchanged.
795: Level: beginner
797: .seealso: `TaoGetTolerances()`
799: @*/
800: PetscErrorCode TaoSetTolerances(Tao tao, PetscReal gatol, PetscReal grtol, PetscReal gttol)
801: {
807: if (gatol != PETSC_DEFAULT) {
808: if (gatol < 0) {
809: PetscInfo(tao, "Tried to set negative gatol -- ignored.\n");
810: } else {
811: tao->gatol = PetscMax(0, gatol);
812: tao->gatol_changed = PETSC_TRUE;
813: }
814: }
816: if (grtol != PETSC_DEFAULT) {
817: if (grtol < 0) {
818: PetscInfo(tao, "Tried to set negative grtol -- ignored.\n");
819: } else {
820: tao->grtol = PetscMax(0, grtol);
821: tao->grtol_changed = PETSC_TRUE;
822: }
823: }
825: if (gttol != PETSC_DEFAULT) {
826: if (gttol < 0) {
827: PetscInfo(tao, "Tried to set negative gttol -- ignored.\n");
828: } else {
829: tao->gttol = PetscMax(0, gttol);
830: tao->gttol_changed = PETSC_TRUE;
831: }
832: }
833: return 0;
834: }
836: /*@
837: TaoSetConstraintTolerances - Sets constraint tolerance parameters used in Tao convergence tests
839: Logically collective on tao
841: Input Parameters:
842: + tao - the Tao context
843: . catol - absolute constraint tolerance, constraint norm must be less than catol for used for gatol convergence criteria
844: - crtol - relative constraint tolerance, constraint norm must be less than crtol for used for gatol, gttol convergence criteria
846: Options Database Keys:
847: + -tao_catol <catol> - Sets catol
848: - -tao_crtol <crtol> - Sets crtol
850: Notes:
851: Use PETSC_DEFAULT to leave any tolerance unchanged.
853: Level: intermediate
855: .seealso: `TaoGetTolerances()`, `TaoGetConstraintTolerances()`, `TaoSetTolerances()`
857: @*/
858: PetscErrorCode TaoSetConstraintTolerances(Tao tao, PetscReal catol, PetscReal crtol)
859: {
864: if (catol != PETSC_DEFAULT) {
865: if (catol < 0) {
866: PetscInfo(tao, "Tried to set negative catol -- ignored.\n");
867: } else {
868: tao->catol = PetscMax(0, catol);
869: tao->catol_changed = PETSC_TRUE;
870: }
871: }
873: if (crtol != PETSC_DEFAULT) {
874: if (crtol < 0) {
875: PetscInfo(tao, "Tried to set negative crtol -- ignored.\n");
876: } else {
877: tao->crtol = PetscMax(0, crtol);
878: tao->crtol_changed = PETSC_TRUE;
879: }
880: }
881: return 0;
882: }
884: /*@
885: TaoGetConstraintTolerances - Gets constraint tolerance parameters used in Tao convergence tests
887: Not ollective
889: Input Parameter:
890: . tao - the Tao context
892: Output Parameters:
893: + catol - absolute constraint tolerance, constraint norm must be less than catol for used for gatol convergence criteria
894: - crtol - relative constraint tolerance, constraint norm must be less than crtol for used for gatol, gttol convergence criteria
896: Level: intermediate
898: .seealso: `TaoGetTolerances()`, `TaoSetTolerances()`, `TaoSetConstraintTolerances()`
900: @*/
901: PetscErrorCode TaoGetConstraintTolerances(Tao tao, PetscReal *catol, PetscReal *crtol)
902: {
904: if (catol) *catol = tao->catol;
905: if (crtol) *crtol = tao->crtol;
906: return 0;
907: }
909: /*@
910: TaoSetFunctionLowerBound - Sets a bound on the solution objective value.
911: When an approximate solution with an objective value below this number
912: has been found, the solver will terminate.
914: Logically Collective on tao
916: Input Parameters:
917: + tao - the Tao solver context
918: - fmin - the tolerance
920: Options Database Keys:
921: . -tao_fmin <fmin> - sets the minimum function value
923: Level: intermediate
925: .seealso: `TaoSetTolerances()`
926: @*/
927: PetscErrorCode TaoSetFunctionLowerBound(Tao tao, PetscReal fmin)
928: {
931: tao->fmin = fmin;
932: tao->fmin_changed = PETSC_TRUE;
933: return 0;
934: }
936: /*@
937: TaoGetFunctionLowerBound - Gets the bound on the solution objective value.
938: When an approximate solution with an objective value below this number
939: has been found, the solver will terminate.
941: Not collective on tao
943: Input Parameters:
944: . tao - the Tao solver context
946: OutputParameters:
947: . fmin - the minimum function value
949: Level: intermediate
951: .seealso: `TaoSetFunctionLowerBound()`
952: @*/
953: PetscErrorCode TaoGetFunctionLowerBound(Tao tao, PetscReal *fmin)
954: {
957: *fmin = tao->fmin;
958: return 0;
959: }
961: /*@
962: TaoSetMaximumFunctionEvaluations - Sets a maximum number of
963: function evaluations.
965: Logically Collective on tao
967: Input Parameters:
968: + tao - the Tao solver context
969: - nfcn - the maximum number of function evaluations (>=0)
971: Options Database Keys:
972: . -tao_max_funcs <nfcn> - sets the maximum number of function evaluations
974: Level: intermediate
976: .seealso: `TaoSetTolerances()`, `TaoSetMaximumIterations()`
977: @*/
979: PetscErrorCode TaoSetMaximumFunctionEvaluations(Tao tao, PetscInt nfcn)
980: {
983: if (nfcn >= 0) {
984: tao->max_funcs = PetscMax(0, nfcn);
985: } else {
986: tao->max_funcs = -1;
987: }
988: tao->max_funcs_changed = PETSC_TRUE;
989: return 0;
990: }
992: /*@
993: TaoGetMaximumFunctionEvaluations - Gets a maximum number of
994: function evaluations.
996: Logically Collective on tao
998: Input Parameters:
999: . tao - the Tao solver context
1001: Output Parameters:
1002: . nfcn - the maximum number of function evaluations
1004: Level: intermediate
1006: .seealso: `TaoSetMaximumFunctionEvaluations()`, `TaoGetMaximumIterations()`
1007: @*/
1009: PetscErrorCode TaoGetMaximumFunctionEvaluations(Tao tao, PetscInt *nfcn)
1010: {
1013: *nfcn = tao->max_funcs;
1014: return 0;
1015: }
1017: /*@
1018: TaoGetCurrentFunctionEvaluations - Get current number of
1019: function evaluations.
1021: Not Collective
1023: Input Parameters:
1024: . tao - the Tao solver context
1026: Output Parameters:
1027: . nfuncs - the current number of function evaluations (maximum between gradient and function evaluations)
1029: Level: intermediate
1031: .seealso: `TaoSetMaximumFunctionEvaluations()`, `TaoGetMaximumFunctionEvaluations()`, `TaoGetMaximumIterations()`
1032: @*/
1034: PetscErrorCode TaoGetCurrentFunctionEvaluations(Tao tao, PetscInt *nfuncs)
1035: {
1038: *nfuncs = PetscMax(tao->nfuncs, tao->nfuncgrads);
1039: return 0;
1040: }
1042: /*@
1043: TaoSetMaximumIterations - Sets a maximum number of iterates.
1045: Logically Collective on tao
1047: Input Parameters:
1048: + tao - the Tao solver context
1049: - maxits - the maximum number of iterates (>=0)
1051: Options Database Keys:
1052: . -tao_max_it <its> - sets the maximum number of iterations
1054: Level: intermediate
1056: .seealso: `TaoSetTolerances()`, `TaoSetMaximumFunctionEvaluations()`
1057: @*/
1058: PetscErrorCode TaoSetMaximumIterations(Tao tao, PetscInt maxits)
1059: {
1062: tao->max_it = PetscMax(0, maxits);
1063: tao->max_it_changed = PETSC_TRUE;
1064: return 0;
1065: }
1067: /*@
1068: TaoGetMaximumIterations - Gets a maximum number of iterates that will be used
1070: Not Collective
1072: Input Parameters:
1073: . tao - the Tao solver context
1075: Output Parameters:
1076: . maxits - the maximum number of iterates
1078: Level: intermediate
1080: .seealso: `TaoSetMaximumIterations()`, `TaoGetMaximumFunctionEvaluations()`
1081: @*/
1082: PetscErrorCode TaoGetMaximumIterations(Tao tao, PetscInt *maxits)
1083: {
1086: *maxits = tao->max_it;
1087: return 0;
1088: }
1090: /*@
1091: TaoSetInitialTrustRegionRadius - Sets the initial trust region radius.
1093: Logically collective on tao
1095: Input Parameters:
1096: + tao - a Tao optimization solver
1097: - radius - the trust region radius
1099: Level: intermediate
1101: Options Database Key:
1102: . -tao_trust0 <t0> - sets initial trust region radius
1104: .seealso: `TaoGetTrustRegionRadius()`, `TaoSetTrustRegionTolerance()`, `TAONTR`
1105: @*/
1106: PetscErrorCode TaoSetInitialTrustRegionRadius(Tao tao, PetscReal radius)
1107: {
1110: tao->trust0 = PetscMax(0.0, radius);
1111: tao->trust0_changed = PETSC_TRUE;
1112: return 0;
1113: }
1115: /*@
1116: TaoGetInitialTrustRegionRadius - Gets the initial trust region radius.
1118: Not Collective
1120: Input Parameter:
1121: . tao - a Tao optimization solver
1123: Output Parameter:
1124: . radius - the trust region radius
1126: Level: intermediate
1128: .seealso: `TaoSetInitialTrustRegionRadius()`, `TaoGetCurrentTrustRegionRadius()`, `TAONTR`
1129: @*/
1130: PetscErrorCode TaoGetInitialTrustRegionRadius(Tao tao, PetscReal *radius)
1131: {
1134: *radius = tao->trust0;
1135: return 0;
1136: }
1138: /*@
1139: TaoGetCurrentTrustRegionRadius - Gets the current trust region radius.
1141: Not Collective
1143: Input Parameter:
1144: . tao - a Tao optimization solver
1146: Output Parameter:
1147: . radius - the trust region radius
1149: Level: intermediate
1151: .seealso: `TaoSetInitialTrustRegionRadius()`, `TaoGetInitialTrustRegionRadius()`, `TAONTR`
1152: @*/
1153: PetscErrorCode TaoGetCurrentTrustRegionRadius(Tao tao, PetscReal *radius)
1154: {
1157: *radius = tao->trust;
1158: return 0;
1159: }
1161: /*@
1162: TaoGetTolerances - gets the current values of tolerances
1164: Not Collective
1166: Input Parameter:
1167: . tao - the Tao context
1169: Output Parameters:
1170: + gatol - stop if norm of gradient is less than this
1171: . grtol - stop if relative norm of gradient is less than this
1172: - gttol - stop if norm of gradient is reduced by a this factor
1174: Note: NULL can be used as an argument if not all tolerances values are needed
1176: .seealso `TaoSetTolerances()`
1178: Level: intermediate
1179: @*/
1180: PetscErrorCode TaoGetTolerances(Tao tao, PetscReal *gatol, PetscReal *grtol, PetscReal *gttol)
1181: {
1183: if (gatol) *gatol = tao->gatol;
1184: if (grtol) *grtol = tao->grtol;
1185: if (gttol) *gttol = tao->gttol;
1186: return 0;
1187: }
1189: /*@
1190: TaoGetKSP - Gets the linear solver used by the optimization solver.
1191: Application writers should use `TaoGetKSP()` if they need direct access
1192: to the PETSc `KSP` object.
1194: Not Collective
1196: Input Parameters:
1197: . tao - the Tao solver
1199: Output Parameters:
1200: . ksp - the KSP linear solver used in the optimization solver
1202: Level: intermediate
1204: .seealso: `Tao`, `KSP`
1205: @*/
1206: PetscErrorCode TaoGetKSP(Tao tao, KSP *ksp)
1207: {
1210: *ksp = tao->ksp;
1211: return 0;
1212: }
1214: /*@
1215: TaoGetLinearSolveIterations - Gets the total number of linear iterations
1216: used by the Tao solver
1218: Not Collective
1220: Input Parameter:
1221: . tao - Tao context
1223: Output Parameter:
1224: . lits - number of linear iterations
1226: Notes:
1227: This counter is reset to zero for each successive call to TaoSolve()
1229: Level: intermediate
1231: .seealso: `Tao`, `TaoGetKSP()`
1232: @*/
1233: PetscErrorCode TaoGetLinearSolveIterations(Tao tao, PetscInt *lits)
1234: {
1237: *lits = tao->ksp_tot_its;
1238: return 0;
1239: }
1241: /*@
1242: TaoGetLineSearch - Gets the line search used by the optimization solver.
1243: Application writers should use `TaoGetLineSearch()` if they need direct access
1244: to the TaoLineSearch object.
1246: Not Collective
1248: Input Parameters:
1249: . tao - the Tao solver
1251: Output Parameters:
1252: . ls - the line search used in the optimization solver
1254: Level: intermediate
1256: @*/
1257: PetscErrorCode TaoGetLineSearch(Tao tao, TaoLineSearch *ls)
1258: {
1261: *ls = tao->linesearch;
1262: return 0;
1263: }
1265: /*@
1266: TaoAddLineSearchCounts - Adds the number of function evaluations spent
1267: in the line search to the running total.
1269: Input Parameters:
1270: + tao - the Tao solver
1271: - ls - the line search used in the optimization solver
1273: Level: developer
1275: .seealso: `TaoGetLineSearch()`, `TaoLineSearchApply()`
1276: @*/
1277: PetscErrorCode TaoAddLineSearchCounts(Tao tao)
1278: {
1279: PetscBool flg;
1280: PetscInt nfeval, ngeval, nfgeval;
1283: if (tao->linesearch) {
1284: TaoLineSearchIsUsingTaoRoutines(tao->linesearch, &flg);
1285: if (!flg) {
1286: TaoLineSearchGetNumberFunctionEvaluations(tao->linesearch, &nfeval, &ngeval, &nfgeval);
1287: tao->nfuncs += nfeval;
1288: tao->ngrads += ngeval;
1289: tao->nfuncgrads += nfgeval;
1290: }
1291: }
1292: return 0;
1293: }
1295: /*@
1296: TaoGetSolution - Returns the vector with the current Tao solution
1298: Not Collective
1300: Input Parameter:
1301: . tao - the Tao context
1303: Output Parameter:
1304: . X - the current solution
1306: Level: intermediate
1308: Note:
1309: The returned vector will be the same object that was passed into `TaoSetSolution()`
1311: .seealso: `Tao`, `TaoSetSolution()`, `TaoSolve()`
1312: @*/
1313: PetscErrorCode TaoGetSolution(Tao tao, Vec *X)
1314: {
1317: *X = tao->solution;
1318: return 0;
1319: }
1321: /*@
1322: TaoResetStatistics - Initialize the statistics used by Tao for all of the solvers.
1323: These statistics include the iteration number, residual norms, and convergence status.
1324: This routine gets called before solving each optimization problem.
1326: Collective on tao
1328: Input Parameters:
1329: . solver - the Tao context
1331: Level: developer
1333: .seealso: `Tao`, `TaoCreate()`, `TaoSolve()`
1334: @*/
1335: PetscErrorCode TaoResetStatistics(Tao tao)
1336: {
1338: tao->niter = 0;
1339: tao->nfuncs = 0;
1340: tao->nfuncgrads = 0;
1341: tao->ngrads = 0;
1342: tao->nhess = 0;
1343: tao->njac = 0;
1344: tao->nconstraints = 0;
1345: tao->ksp_its = 0;
1346: tao->ksp_tot_its = 0;
1347: tao->reason = TAO_CONTINUE_ITERATING;
1348: tao->residual = 0.0;
1349: tao->cnorm = 0.0;
1350: tao->step = 0.0;
1351: tao->lsflag = PETSC_FALSE;
1352: if (tao->hist_reset) tao->hist_len = 0;
1353: return 0;
1354: }
1356: /*@C
1357: TaoSetUpdate - Sets the general-purpose update function called
1358: at the beginning of every iteration of the optimization algorithm. Specifically
1359: it is called at the top of every iteration, after the new solution and the gradient
1360: is determined, but before the Hessian is computed (if applicable).
1362: Logically Collective on tao
1364: Input Parameters:
1365: + tao - The tao solver context
1366: - func - The function
1368: Calling sequence of func:
1369: $ func (Tao tao, PetscInt step);
1371: . step - The current step of the iteration
1373: Level: advanced
1375: .seealso `Tao`, `TaoSolve()`
1376: @*/
1377: PetscErrorCode TaoSetUpdate(Tao tao, PetscErrorCode (*func)(Tao, PetscInt, void *), void *ctx)
1378: {
1380: tao->ops->update = func;
1381: tao->user_update = ctx;
1382: return 0;
1383: }
1385: /*@C
1386: TaoSetConvergenceTest - Sets the function that is to be used to test
1387: for convergence o fthe iterative minimization solution. The new convergence
1388: testing routine will replace Tao's default convergence test.
1390: Logically Collective on tao
1392: Input Parameters:
1393: + tao - the Tao object
1394: . conv - the routine to test for convergence
1395: - ctx - [optional] context for private data for the convergence routine
1396: (may be NULL)
1398: Calling sequence of conv:
1399: $ PetscErrorCode conv(Tao tao, void *ctx)
1401: + tao - the Tao object
1402: - ctx - [optional] convergence context
1404: Note:
1405: The new convergence testing routine should call `TaoSetConvergedReason()`.
1407: Level: advanced
1409: .seealso: `Tao`, `TaoSolve()`, `TaoSetConvergedReason()`, `TaoGetSolutionStatus()`, `TaoGetTolerances()`, `TaoSetMonitor`
1411: @*/
1412: PetscErrorCode TaoSetConvergenceTest(Tao tao, PetscErrorCode (*conv)(Tao, void *), void *ctx)
1413: {
1415: tao->ops->convergencetest = conv;
1416: tao->cnvP = ctx;
1417: return 0;
1418: }
1420: /*@C
1421: TaoSetMonitor - Sets an additional function that is to be used at every
1422: iteration of the solver to display the iteration's
1423: progress.
1425: Logically Collective on tao
1427: Input Parameters:
1428: + tao - the Tao solver context
1429: . mymonitor - monitoring routine
1430: - mctx - [optional] user-defined context for private data for the
1431: monitor routine (may be NULL)
1433: Calling sequence of mymonitor:
1434: .vb
1435: PetscErrorCode mymonitor(Tao tao,void *mctx)
1436: .ve
1438: + tao - the Tao solver context
1439: - mctx - [optional] monitoring context
1441: Options Database Keys:
1442: + -tao_monitor - sets the default monitor `TaoMonitorDefault()`
1443: . -tao_smonitor - sets short monitor
1444: . -tao_cmonitor - same as smonitor plus constraint norm
1445: . -tao_view_solution - view solution at each iteration
1446: . -tao_view_gradient - view gradient at each iteration
1447: . -tao_view_ls_residual - view least-squares residual vector at each iteration
1448: - -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.
1450: Notes:
1451: Several different monitoring routines may be set by calling
1452: `TaoSetMonitor()` multiple times; all will be called in the
1453: order in which they were set.
1455: Fortran Note:
1456: Only one monitor function may be set
1458: Level: intermediate
1460: .seealso: `Tao`, `TaoSolve()`, `TaoMonitorDefault()`, `TaoCancelMonitors()`, `TaoSetDestroyRoutine()`, `TaoView()`
1461: @*/
1462: PetscErrorCode TaoSetMonitor(Tao tao, PetscErrorCode (*func)(Tao, void *), void *ctx, PetscErrorCode (*dest)(void **))
1463: {
1464: PetscInt i;
1465: PetscBool identical;
1470: for (i = 0; i < tao->numbermonitors; i++) {
1471: PetscMonitorCompare((PetscErrorCode(*)(void))func, ctx, dest, (PetscErrorCode(*)(void))tao->monitor[i], tao->monitorcontext[i], tao->monitordestroy[i], &identical);
1472: if (identical) return 0;
1473: }
1474: tao->monitor[tao->numbermonitors] = func;
1475: tao->monitorcontext[tao->numbermonitors] = (void *)ctx;
1476: tao->monitordestroy[tao->numbermonitors] = dest;
1477: ++tao->numbermonitors;
1478: return 0;
1479: }
1481: /*@
1482: TaoCancelMonitors - Clears all the monitor functions for a Tao object.
1484: Logically Collective on tao
1486: Input Parameters:
1487: . tao - the Tao solver context
1489: Options Database:
1490: . -tao_cancelmonitors - cancels all monitors that have been hardwired
1491: into a code by calls to `TaoSetMonitor()`, but does not cancel those
1492: set via the options database
1494: Notes:
1495: There is no way to clear one specific monitor from a Tao object.
1497: Level: advanced
1499: .seealso: `Tao`, `TaoMonitorDefault()`, `TaoSetMonitor()`
1500: @*/
1501: PetscErrorCode TaoCancelMonitors(Tao tao)
1502: {
1503: PetscInt i;
1506: for (i = 0; i < tao->numbermonitors; i++) {
1507: if (tao->monitordestroy[i]) (*tao->monitordestroy[i])(&tao->monitorcontext[i]);
1508: }
1509: tao->numbermonitors = 0;
1510: return 0;
1511: }
1513: /*@
1514: TaoMonitorDefault - Default routine for monitoring progress of the
1515: Tao solvers (default). This monitor prints the function value and gradient
1516: norm at each iteration. It can be turned on from the command line using the
1517: -tao_monitor option
1519: Collective on tao
1521: Input Parameters:
1522: + tao - the Tao context
1523: - ctx - `PetscViewer` context or NULL
1525: Options Database Keys:
1526: . -tao_monitor - turn on default monitoring
1528: Level: advanced
1530: .seealso: `TaoDefaultSMonitor()`, `TaoSetMonitor()`
1531: @*/
1532: PetscErrorCode TaoMonitorDefault(Tao tao, void *ctx)
1533: {
1534: PetscInt its, tabs;
1535: PetscReal fct, gnorm;
1536: PetscViewer viewer = (PetscViewer)ctx;
1540: its = tao->niter;
1541: fct = tao->fc;
1542: gnorm = tao->residual;
1543: PetscViewerASCIIGetTab(viewer, &tabs);
1544: PetscViewerASCIISetTab(viewer, ((PetscObject)tao)->tablevel);
1545: if (its == 0 && ((PetscObject)tao)->prefix && !tao->header_printed) {
1546: PetscViewerASCIIPrintf(viewer, " Iteration information for %s solve.\n", ((PetscObject)tao)->prefix);
1547: tao->header_printed = PETSC_TRUE;
1548: }
1549: PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " TAO,", its);
1550: PetscViewerASCIIPrintf(viewer, " Function value: %g,", (double)fct);
1551: if (gnorm >= PETSC_INFINITY) {
1552: PetscViewerASCIIPrintf(viewer, " Residual: Inf \n");
1553: } else {
1554: PetscViewerASCIIPrintf(viewer, " Residual: %g \n", (double)gnorm);
1555: }
1556: PetscViewerASCIISetTab(viewer, tabs);
1557: return 0;
1558: }
1560: /*@
1561: TaoDefaultGMonitor - Default routine for monitoring progress of the
1562: Tao solvers (default) with extra detail on the globalization method.
1563: This monitor prints the function value and gradient norm at each
1564: iteration, as well as the step size and trust radius. Note that the
1565: step size and trust radius may be the same for some algorithms.
1566: It can be turned on from the command line using the
1567: -tao_gmonitor option
1569: Collective on tao
1571: Input Parameters:
1572: + tao - the Tao context
1573: - ctx - `PetscViewer` context or NULL
1575: Options Database Keys:
1576: . -tao_gmonitor - turn on monitoring with globalization information
1578: Level: advanced
1580: .seealso: `TaoDefaultSMonitor()`, `TaoSetMonitor()`
1581: @*/
1582: PetscErrorCode TaoDefaultGMonitor(Tao tao, void *ctx)
1583: {
1584: PetscInt its, tabs;
1585: PetscReal fct, gnorm, stp, tr;
1586: PetscViewer viewer = (PetscViewer)ctx;
1590: its = tao->niter;
1591: fct = tao->fc;
1592: gnorm = tao->residual;
1593: stp = tao->step;
1594: tr = tao->trust;
1595: PetscViewerASCIIGetTab(viewer, &tabs);
1596: PetscViewerASCIISetTab(viewer, ((PetscObject)tao)->tablevel);
1597: if (its == 0 && ((PetscObject)tao)->prefix && !tao->header_printed) {
1598: PetscViewerASCIIPrintf(viewer, " Iteration information for %s solve.\n", ((PetscObject)tao)->prefix);
1599: tao->header_printed = PETSC_TRUE;
1600: }
1601: PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " TAO,", its);
1602: PetscViewerASCIIPrintf(viewer, " Function value: %g,", (double)fct);
1603: if (gnorm >= PETSC_INFINITY) {
1604: PetscViewerASCIIPrintf(viewer, " Residual: Inf,");
1605: } else {
1606: PetscViewerASCIIPrintf(viewer, " Residual: %g,", (double)gnorm);
1607: }
1608: PetscViewerASCIIPrintf(viewer, " Step: %g, Trust: %g\n", (double)stp, (double)tr);
1609: PetscViewerASCIISetTab(viewer, tabs);
1610: return 0;
1611: }
1613: /*@
1614: TaoDefaultSMonitor - Default routine for monitoring progress of the
1615: solver. Same as `TaoMonitorDefault()` except
1616: it prints fewer digits of the residual as the residual gets smaller.
1617: This is because the later digits are meaningless and are often
1618: different on different machines; by using this routine different
1619: machines will usually generate the same output. It can be turned on
1620: by using the -tao_smonitor option
1622: Collective on tao
1624: Input Parameters:
1625: + tao - the Tao context
1626: - ctx - PetscViewer context of type ASCII
1628: Options Database Keys:
1629: . -tao_smonitor - turn on default short monitoring
1631: Level: advanced
1633: .seealso: `TaoMonitorDefault()`, `TaoSetMonitor()`
1634: @*/
1635: PetscErrorCode TaoDefaultSMonitor(Tao tao, void *ctx)
1636: {
1637: PetscInt its, tabs;
1638: PetscReal fct, gnorm;
1639: PetscViewer viewer = (PetscViewer)ctx;
1643: its = tao->niter;
1644: fct = tao->fc;
1645: gnorm = tao->residual;
1646: PetscViewerASCIIGetTab(viewer, &tabs);
1647: PetscViewerASCIISetTab(viewer, ((PetscObject)tao)->tablevel);
1648: PetscViewerASCIIPrintf(viewer, "iter = %3" PetscInt_FMT ",", its);
1649: PetscViewerASCIIPrintf(viewer, " Function value %g,", (double)fct);
1650: if (gnorm >= PETSC_INFINITY) {
1651: PetscViewerASCIIPrintf(viewer, " Residual: Inf \n");
1652: } else if (gnorm > 1.e-6) {
1653: PetscViewerASCIIPrintf(viewer, " Residual: %g \n", (double)gnorm);
1654: } else if (gnorm > 1.e-11) {
1655: PetscViewerASCIIPrintf(viewer, " Residual: < 1.0e-6 \n");
1656: } else {
1657: PetscViewerASCIIPrintf(viewer, " Residual: < 1.0e-11 \n");
1658: }
1659: PetscViewerASCIISetTab(viewer, tabs);
1660: return 0;
1661: }
1663: /*@
1664: TaoDefaultCMonitor - same as `TaoMonitorDefault()` except
1665: it prints the norm of the constraints function. It can be turned on
1666: from the command line using the -tao_cmonitor option
1668: Collective on tao
1670: Input Parameters:
1671: + tao - the Tao context
1672: - ctx - `PetscViewer` context or NULL
1674: Options Database Keys:
1675: . -tao_cmonitor - monitor the constraints
1677: Level: advanced
1679: .seealso: `TaoMonitorDefault()`, `TaoSetMonitor()`
1680: @*/
1681: PetscErrorCode TaoDefaultCMonitor(Tao tao, void *ctx)
1682: {
1683: PetscInt its, tabs;
1684: PetscReal fct, gnorm;
1685: PetscViewer viewer = (PetscViewer)ctx;
1689: its = tao->niter;
1690: fct = tao->fc;
1691: gnorm = tao->residual;
1692: PetscViewerASCIIGetTab(viewer, &tabs);
1693: PetscViewerASCIISetTab(viewer, ((PetscObject)tao)->tablevel);
1694: PetscViewerASCIIPrintf(viewer, "iter = %" PetscInt_FMT ",", its);
1695: PetscViewerASCIIPrintf(viewer, " Function value: %g,", (double)fct);
1696: PetscViewerASCIIPrintf(viewer, " Residual: %g ", (double)gnorm);
1697: PetscViewerASCIIPrintf(viewer, " Constraint: %g \n", (double)tao->cnorm);
1698: PetscViewerASCIISetTab(viewer, tabs);
1699: return 0;
1700: }
1702: /*@C
1703: TaoSolutionMonitor - Views the solution at each iteration
1704: It can be turned on from the command line using the
1705: -tao_view_solution option
1707: Collective on tao
1709: Input Parameters:
1710: + tao - the Tao context
1711: - ctx - `PetscViewer` context or NULL
1713: Options Database Keys:
1714: . -tao_view_solution - view the solution
1716: Level: advanced
1718: .seealso: `TaoDefaultSMonitor()`, `TaoSetMonitor()`
1719: @*/
1720: PetscErrorCode TaoSolutionMonitor(Tao tao, void *ctx)
1721: {
1722: PetscViewer viewer = (PetscViewer)ctx;
1726: VecView(tao->solution, viewer);
1727: return 0;
1728: }
1730: /*@C
1731: TaoGradientMonitor - Views the gradient at each iteration
1732: It can be turned on from the command line using the
1733: -tao_view_gradient option
1735: Collective on tao
1737: Input Parameters:
1738: + tao - the Tao context
1739: - ctx - `PetscViewer` context or NULL
1741: Options Database Keys:
1742: . -tao_view_gradient - view the gradient at each iteration
1744: Level: advanced
1746: .seealso: `TaoDefaultSMonitor()`, `TaoSetMonitor()`
1747: @*/
1748: PetscErrorCode TaoGradientMonitor(Tao tao, void *ctx)
1749: {
1750: PetscViewer viewer = (PetscViewer)ctx;
1754: VecView(tao->gradient, viewer);
1755: return 0;
1756: }
1758: /*@C
1759: TaoStepDirectionMonitor - Views the step-direction at each iteration
1761: Collective on tao
1763: Input Parameters:
1764: + tao - the Tao context
1765: - ctx - `PetscViewer` context or NULL
1767: Options Database Keys:
1768: . -tao_view_gradient - view the gradient at each iteration
1770: Level: advanced
1772: .seealso: `TaoDefaultSMonitor()`, `TaoSetMonitor()`
1773: @*/
1774: PetscErrorCode TaoStepDirectionMonitor(Tao tao, void *ctx)
1775: {
1776: PetscViewer viewer = (PetscViewer)ctx;
1780: VecView(tao->stepdirection, viewer);
1781: return 0;
1782: }
1784: /*@C
1785: TaoDrawSolutionMonitor - Plots the solution at each iteration
1786: It can be turned on from the command line using the
1787: -tao_draw_solution option
1789: Collective on tao
1791: Input Parameters:
1792: + tao - the Tao context
1793: - ctx - `TaoMonitorDraw` context
1795: Options Database Keys:
1796: . -tao_draw_solution - draw the solution at each iteration
1798: Level: advanced
1800: .seealso: `TaoSolutionMonitor()`, `TaoSetMonitor()`, `TaoDrawGradientMonitor`, `TaoMonitorDraw`
1801: @*/
1802: PetscErrorCode TaoDrawSolutionMonitor(Tao tao, void *ctx)
1803: {
1804: TaoMonitorDrawCtx ictx = (TaoMonitorDrawCtx)ctx;
1807: if (!(((ictx->howoften > 0) && (!(tao->niter % ictx->howoften))) || ((ictx->howoften == -1) && tao->reason))) return 0;
1808: VecView(tao->solution, ictx->viewer);
1809: return 0;
1810: }
1812: /*@C
1813: TaoDrawGradientMonitor - Plots the gradient at each iteration
1814: It can be turned on from the command line using the
1815: -tao_draw_gradient option
1817: Collective on tao
1819: Input Parameters:
1820: + tao - the Tao context
1821: - ctx - `PetscViewer` context
1823: Options Database Keys:
1824: . -tao_draw_gradient - draw the gradient at each iteration
1826: Level: advanced
1828: .seealso: `TaoGradientMonitor()`, `TaoSetMonitor()`, `TaoDrawSolutionMonitor`
1829: @*/
1830: PetscErrorCode TaoDrawGradientMonitor(Tao tao, void *ctx)
1831: {
1832: TaoMonitorDrawCtx ictx = (TaoMonitorDrawCtx)ctx;
1835: if (!(((ictx->howoften > 0) && (!(tao->niter % ictx->howoften))) || ((ictx->howoften == -1) && tao->reason))) return 0;
1836: VecView(tao->gradient, ictx->viewer);
1837: return 0;
1838: }
1840: /*@C
1841: TaoDrawStepMonitor - Plots the step direction at each iteration
1843: Collective on tao
1845: Input Parameters:
1846: + tao - the Tao context
1847: - ctx - PetscViewer context
1849: Options Database Keys:
1850: . -tao_draw_step - draw the step direction at each iteration
1852: Level: advanced
1854: .seealso: `TaoSetMonitor()`, `TaoDrawSolutionMonitor`
1855: @*/
1856: PetscErrorCode TaoDrawStepMonitor(Tao tao, void *ctx)
1857: {
1858: PetscViewer viewer = (PetscViewer)ctx;
1862: VecView(tao->stepdirection, viewer);
1863: return 0;
1864: }
1866: /*@C
1867: TaoResidualMonitor - Views the least-squares residual at each iteration
1869: Collective on tao
1871: Input Parameters:
1872: + tao - the Tao context
1873: - ctx - `PetscViewer` context or NULL
1875: Options Database Keys:
1876: . -tao_view_ls_residual - view the least-squares residual at each iteration
1878: Level: advanced
1880: .seealso: `TaoDefaultSMonitor()`, `TaoSetMonitor()`
1881: @*/
1882: PetscErrorCode TaoResidualMonitor(Tao tao, void *ctx)
1883: {
1884: PetscViewer viewer = (PetscViewer)ctx;
1888: VecView(tao->ls_res, viewer);
1889: return 0;
1890: }
1892: /*@
1893: TaoDefaultConvergenceTest - Determines whether the solver should continue iterating
1894: or terminate.
1896: Collective on tao
1898: Input Parameters:
1899: + tao - the Tao context
1900: - dummy - unused dummy context
1902: Output Parameter:
1903: . reason - for terminating
1905: Notes:
1906: This routine checks the residual in the optimality conditions, the
1907: relative residual in the optimity conditions, the number of function
1908: evaluations, and the function value to test convergence. Some
1909: solvers may use different convergence routines.
1911: Level: developer
1913: .seealso: `TaoSetTolerances()`, `TaoGetConvergedReason()`, `TaoSetConvergedReason()`
1914: @*/
1916: PetscErrorCode TaoDefaultConvergenceTest(Tao tao, void *dummy)
1917: {
1918: PetscInt niter = tao->niter, nfuncs = PetscMax(tao->nfuncs, tao->nfuncgrads);
1919: PetscInt max_funcs = tao->max_funcs;
1920: PetscReal gnorm = tao->residual, gnorm0 = tao->gnorm0;
1921: PetscReal f = tao->fc, steptol = tao->steptol, trradius = tao->step;
1922: PetscReal gatol = tao->gatol, grtol = tao->grtol, gttol = tao->gttol;
1923: PetscReal catol = tao->catol, crtol = tao->crtol;
1924: PetscReal fmin = tao->fmin, cnorm = tao->cnorm;
1925: TaoConvergedReason reason = tao->reason;
1928: if (reason != TAO_CONTINUE_ITERATING) return 0;
1930: if (PetscIsInfOrNanReal(f)) {
1931: PetscInfo(tao, "Failed to converged, function value is Inf or NaN\n");
1932: reason = TAO_DIVERGED_NAN;
1933: } else if (f <= fmin && cnorm <= catol) {
1934: PetscInfo(tao, "Converged due to function value %g < minimum function value %g\n", (double)f, (double)fmin);
1935: reason = TAO_CONVERGED_MINF;
1936: } else if (gnorm <= gatol && cnorm <= catol) {
1937: PetscInfo(tao, "Converged due to residual norm ||g(X)||=%g < %g\n", (double)gnorm, (double)gatol);
1938: reason = TAO_CONVERGED_GATOL;
1939: } else if (f != 0 && PetscAbsReal(gnorm / f) <= grtol && cnorm <= crtol) {
1940: PetscInfo(tao, "Converged due to residual ||g(X)||/|f(X)| =%g < %g\n", (double)(gnorm / f), (double)grtol);
1941: reason = TAO_CONVERGED_GRTOL;
1942: } else if (gnorm0 != 0 && ((gttol == 0 && gnorm == 0) || gnorm / gnorm0 < gttol) && cnorm <= crtol) {
1943: PetscInfo(tao, "Converged due to relative residual norm ||g(X)||/||g(X0)|| = %g < %g\n", (double)(gnorm / gnorm0), (double)gttol);
1944: reason = TAO_CONVERGED_GTTOL;
1945: } else if (max_funcs >= 0 && nfuncs > max_funcs) {
1946: PetscInfo(tao, "Exceeded maximum number of function evaluations: %" PetscInt_FMT " > %" PetscInt_FMT "\n", nfuncs, max_funcs);
1947: reason = TAO_DIVERGED_MAXFCN;
1948: } else if (tao->lsflag != 0) {
1949: PetscInfo(tao, "Tao Line Search failure.\n");
1950: reason = TAO_DIVERGED_LS_FAILURE;
1951: } else if (trradius < steptol && niter > 0) {
1952: PetscInfo(tao, "Trust region/step size too small: %g < %g\n", (double)trradius, (double)steptol);
1953: reason = TAO_CONVERGED_STEPTOL;
1954: } else if (niter >= tao->max_it) {
1955: PetscInfo(tao, "Exceeded maximum number of iterations: %" PetscInt_FMT " > %" PetscInt_FMT "\n", niter, tao->max_it);
1956: reason = TAO_DIVERGED_MAXITS;
1957: } else {
1958: reason = TAO_CONTINUE_ITERATING;
1959: }
1960: tao->reason = reason;
1961: return 0;
1962: }
1964: /*@C
1965: TaoSetOptionsPrefix - Sets the prefix used for searching for all
1966: Tao options in the database.
1968: Logically Collective on tao
1970: Input Parameters:
1971: + tao - the Tao context
1972: - prefix - the prefix string to prepend to all Tao option requests
1974: Notes:
1975: A hyphen (-) must NOT be given at the beginning of the prefix name.
1976: The first character of all runtime options is AUTOMATICALLY the hyphen.
1978: For example, to distinguish between the runtime options for two
1979: different Tao solvers, one could call
1980: .vb
1981: TaoSetOptionsPrefix(tao1,"sys1_")
1982: TaoSetOptionsPrefix(tao2,"sys2_")
1983: .ve
1985: This would enable use of different options for each system, such as
1986: .vb
1987: -sys1_tao_method blmvm -sys1_tao_grtol 1.e-3
1988: -sys2_tao_method lmvm -sys2_tao_grtol 1.e-4
1989: .ve
1991: Level: advanced
1993: .seealso: `TaoSetFromOptions()`, `TaoAppendOptionsPrefix()`, `TaoGetOptionsPrefix()`
1994: @*/
1996: PetscErrorCode TaoSetOptionsPrefix(Tao tao, const char p[])
1997: {
1999: PetscObjectSetOptionsPrefix((PetscObject)tao, p);
2000: if (tao->linesearch) TaoLineSearchSetOptionsPrefix(tao->linesearch, p);
2001: if (tao->ksp) KSPSetOptionsPrefix(tao->ksp, p);
2002: return 0;
2003: }
2005: /*@C
2006: TaoAppendOptionsPrefix - Appends to the prefix used for searching for all
2007: Tao options in the database.
2009: Logically Collective on tao
2011: Input Parameters:
2012: + tao - the Tao solver context
2013: - prefix - the prefix string to prepend to all Tao option requests
2015: Note:
2016: A hyphen (-) must NOT be given at the beginning of the prefix name.
2017: The first character of all runtime options is automatically the hyphen.
2019: Level: advanced
2021: .seealso: `TaoSetFromOptions()`, `TaoSetOptionsPrefix()`, `TaoGetOptionsPrefix()`
2022: @*/
2023: PetscErrorCode TaoAppendOptionsPrefix(Tao tao, const char p[])
2024: {
2026: PetscObjectAppendOptionsPrefix((PetscObject)tao, p);
2027: if (tao->linesearch) PetscObjectAppendOptionsPrefix((PetscObject)tao->linesearch, p);
2028: if (tao->ksp) KSPAppendOptionsPrefix(tao->ksp, p);
2029: return 0;
2030: }
2032: /*@C
2033: TaoGetOptionsPrefix - Gets the prefix used for searching for all
2034: Tao options in the database
2036: Not Collective
2038: Input Parameters:
2039: . tao - the Tao context
2041: Output Parameters:
2042: . prefix - pointer to the prefix string used is returned
2044: Fortran Note:
2045: On the fortran side, the user should pass in a string 'prefix' of
2046: sufficient length to hold the prefix.
2048: Level: advanced
2050: .seealso: `TaoSetFromOptions()`, `TaoSetOptionsPrefix()`, `TaoAppendOptionsPrefix()`
2051: @*/
2052: PetscErrorCode TaoGetOptionsPrefix(Tao tao, const char *p[])
2053: {
2055: PetscObjectGetOptionsPrefix((PetscObject)tao, p);
2056: return 0;
2057: }
2059: /*@C
2060: TaoSetType - Sets the method for the unconstrained minimization solver.
2062: Collective on tao
2064: Input Parameters:
2065: + solver - the Tao solver context
2066: - type - a known method
2068: Options Database Key:
2069: . -tao_type <type> - Sets the method; use -help for a list
2070: of available methods (for instance, "-tao_type lmvm" or "-tao_type tron")
2072: Available methods include:
2073: + `TAONLS` - nls Newton's method with line search for unconstrained minimization
2074: . `TAONTR` - ntr Newton's method with trust region for unconstrained minimization
2075: . `TAONTL` - ntl Newton's method with trust region, line search for unconstrained minimization
2076: . `TAOLMVM` - lmvm Limited memory variable metric method for unconstrained minimization
2077: . `TAOCG` - cg Nonlinear conjugate gradient method for unconstrained minimization
2078: . `TAONM` - nm Nelder-Mead algorithm for derivate-free unconstrained minimization
2079: . `TAOTRON` - tron Newton Trust Region method for bound constrained minimization
2080: . `TAOGPCG` - gpcg Newton Trust Region method for quadratic bound constrained minimization
2081: . `TAOBLMVM` - blmvm Limited memory variable metric method for bound constrained minimization
2082: . `TAOLCL` - lcl Linearly constrained Lagrangian method for pde-constrained minimization
2083: - `TAOPOUNDERS` - pounders Model-based algorithm for nonlinear least squares
2085: Level: intermediate
2087: .seealso: `Tao`, `TaoCreate()`, `TaoGetType()`, `TaoType`
2089: @*/
2090: PetscErrorCode TaoSetType(Tao tao, TaoType type)
2091: {
2092: PetscErrorCode (*create_xxx)(Tao);
2093: PetscBool issame;
2097: PetscObjectTypeCompare((PetscObject)tao, type, &issame);
2098: if (issame) return 0;
2100: PetscFunctionListFind(TaoList, type, (void (**)(void)) & create_xxx);
2103: /* Destroy the existing solver information */
2104: PetscTryTypeMethod(tao, destroy);
2105: KSPDestroy(&tao->ksp);
2106: TaoLineSearchDestroy(&tao->linesearch);
2107: tao->ops->setup = NULL;
2108: tao->ops->solve = NULL;
2109: tao->ops->view = NULL;
2110: tao->ops->setfromoptions = NULL;
2111: tao->ops->destroy = NULL;
2113: tao->setupcalled = PETSC_FALSE;
2115: (*create_xxx)(tao);
2116: PetscObjectChangeTypeName((PetscObject)tao, type);
2117: return 0;
2118: }
2120: /*MC
2121: TaoRegister - Adds a method to the Tao package for unconstrained minimization.
2123: Synopsis:
2124: TaoRegister(char *name_solver,char *path,char *name_Create,PetscErrorCode (*routine_Create)(Tao))
2126: Not collective
2128: Input Parameters:
2129: + sname - name of a new user-defined solver
2130: - func - routine to Create method context
2132: Note:
2133: `TaoRegister()` may be called multiple times to add several user-defined solvers.
2135: Sample usage:
2136: .vb
2137: TaoRegister("my_solver",MySolverCreate);
2138: .ve
2140: Then, your solver can be chosen with the procedural interface via
2141: $ TaoSetType(tao,"my_solver")
2142: or at runtime via the option
2143: $ -tao_type my_solver
2145: Level: advanced
2147: .seealso: `Tao`, `TaoSetType()`, `TaoRegisterAll()`, `TaoRegisterDestroy()`
2148: M*/
2149: PetscErrorCode TaoRegister(const char sname[], PetscErrorCode (*func)(Tao))
2150: {
2151: TaoInitializePackage();
2152: PetscFunctionListAdd(&TaoList, sname, (void (*)(void))func);
2153: return 0;
2154: }
2156: /*@C
2157: TaoRegisterDestroy - Frees the list of minimization solvers that were
2158: registered by `TaoRegisterDynamic()`.
2160: Not Collective
2162: Level: advanced
2164: .seealso: `TaoRegisterAll()`, `TaoRegister()`
2165: @*/
2166: PetscErrorCode TaoRegisterDestroy(void)
2167: {
2168: PetscFunctionListDestroy(&TaoList);
2169: TaoRegisterAllCalled = PETSC_FALSE;
2170: return 0;
2171: }
2173: /*@
2174: TaoGetIterationNumber - Gets the number of Tao iterations completed
2175: at this time.
2177: Not Collective
2179: Input Parameter:
2180: . tao - Tao context
2182: Output Parameter:
2183: . iter - iteration number
2185: Notes:
2186: For example, during the computation of iteration 2 this would return 1.
2188: Level: intermediate
2190: .seealso: `TaoGetLinearSolveIterations()`, `TaoGetResidualNorm()`, `TaoGetObjective()`
2191: @*/
2192: PetscErrorCode TaoGetIterationNumber(Tao tao, PetscInt *iter)
2193: {
2196: *iter = tao->niter;
2197: return 0;
2198: }
2200: /*@
2201: TaoGetResidualNorm - Gets the current value of the norm of the residual
2202: at this time.
2204: Not Collective
2206: Input Parameter:
2207: . tao - Tao context
2209: Output Parameter:
2210: . value - the current value
2212: Level: intermediate
2214: Developer Note: This is the 2-norm of the residual, we cannot use `TaoGetGradientNorm()` because that has
2215: a different meaning. For some reason Tao sometimes calls the gradient the residual.
2217: .seealso: `TaoGetLinearSolveIterations()`, `TaoGetIterationNumber()`, `TaoGetObjective()`
2218: @*/
2219: PetscErrorCode TaoGetResidualNorm(Tao tao, PetscReal *value)
2220: {
2223: *value = tao->residual;
2224: return 0;
2225: }
2227: /*@
2228: TaoSetIterationNumber - Sets the current iteration number.
2230: Logically Collective on tao
2232: Input Parameters:
2233: + tao - Tao context
2234: - iter - iteration number
2236: Level: developer
2238: .seealso: `TaoGetLinearSolveIterations()`
2239: @*/
2240: PetscErrorCode TaoSetIterationNumber(Tao tao, PetscInt iter)
2241: {
2244: PetscObjectSAWsTakeAccess((PetscObject)tao);
2245: tao->niter = iter;
2246: PetscObjectSAWsGrantAccess((PetscObject)tao);
2247: return 0;
2248: }
2250: /*@
2251: TaoGetTotalIterationNumber - Gets the total number of Tao iterations
2252: completed. This number keeps accumulating if multiple solves
2253: are called with the Tao object.
2255: Not Collective
2257: Input Parameter:
2258: . tao - Tao context
2260: Output Parameter:
2261: . iter - iteration number
2263: Notes:
2264: The total iteration count is updated after each solve, if there is a current
2265: TaoSolve() in progress then those iterations are not yet counted.
2267: Level: intermediate
2269: .seealso: `TaoGetLinearSolveIterations()`
2270: @*/
2271: PetscErrorCode TaoGetTotalIterationNumber(Tao tao, PetscInt *iter)
2272: {
2275: *iter = tao->ntotalits;
2276: return 0;
2277: }
2279: /*@
2280: TaoSetTotalIterationNumber - Sets the current total iteration number.
2282: Logically Collective on tao
2284: Input Parameters:
2285: + tao - Tao context
2286: - iter - iteration number
2288: Level: developer
2290: .seealso: `TaoGetLinearSolveIterations()`
2291: @*/
2292: PetscErrorCode TaoSetTotalIterationNumber(Tao tao, PetscInt iter)
2293: {
2296: PetscObjectSAWsTakeAccess((PetscObject)tao);
2297: tao->ntotalits = iter;
2298: PetscObjectSAWsGrantAccess((PetscObject)tao);
2299: return 0;
2300: }
2302: /*@
2303: TaoSetConvergedReason - Sets the termination flag on a Tao object
2305: Logically Collective on tao
2307: Input Parameters:
2308: + tao - the Tao context
2309: - reason - one of
2310: $ `TAO_CONVERGED_ATOL` (2),
2311: $ `TAO_CONVERGED_RTOL` (3),
2312: $ `TAO_CONVERGED_STEPTOL` (4),
2313: $ `TAO_CONVERGED_MINF` (5),
2314: $ `TAO_CONVERGED_USER` (6),
2315: $ `TAO_DIVERGED_MAXITS` (-2),
2316: $ `TAO_DIVERGED_NAN` (-4),
2317: $ `TAO_DIVERGED_MAXFCN` (-5),
2318: $ `TAO_DIVERGED_LS_FAILURE` (-6),
2319: $ `TAO_DIVERGED_TR_REDUCTION` (-7),
2320: $ `TAO_DIVERGED_USER` (-8),
2321: $ `TAO_CONTINUE_ITERATING` (0)
2323: Level: intermediate
2325: @*/
2326: PetscErrorCode TaoSetConvergedReason(Tao tao, TaoConvergedReason reason)
2327: {
2330: tao->reason = reason;
2331: return 0;
2332: }
2334: /*@
2335: TaoGetConvergedReason - Gets the reason the Tao iteration was stopped.
2337: Not Collective
2339: Input Parameter:
2340: . tao - the Tao solver context
2342: Output Parameter:
2343: . reason - one of
2344: $ `TAO_CONVERGED_GATOL` (3) ||g(X)|| < gatol
2345: $ `TAO_CONVERGED_GRTOL` (4) ||g(X)|| / f(X) < grtol
2346: $ `TAO_CONVERGED_GTTOL` (5) ||g(X)|| / ||g(X0)|| < gttol
2347: $ `TAO_CONVERGED_STEPTOL` (6) step size small
2348: $ `TAO_CONVERGED_MINF` (7) F < F_min
2349: $ `TAO_CONVERGED_USER` (8) User defined
2350: $ `TAO_DIVERGED_MAXITS` (-2) its > maxits
2351: $ `TAO_DIVERGED_NAN` (-4) Numerical problems
2352: $ `TAO_DIVERGED_MAXFCN` (-5) fevals > max_funcsals
2353: $ `TAO_DIVERGED_LS_FAILURE` (-6) line search failure
2354: $ `TAO_DIVERGED_TR_REDUCTION` (-7) trust region failure
2355: $ `TAO_DIVERGED_USER` (-8) (user defined)
2356: $ `TAO_CONTINUE_ITERATING` (0)
2358: where
2359: + X - current solution
2360: . X0 - initial guess
2361: . f(X) - current function value
2362: . f(X*) - true solution (estimated)
2363: . g(X) - current gradient
2364: . its - current iterate number
2365: . maxits - maximum number of iterates
2366: . fevals - number of function evaluations
2367: - max_funcsals - maximum number of function evaluations
2369: Level: intermediate
2371: .seealso: `TaoSetConvergenceTest()`, `TaoSetTolerances()`
2373: @*/
2374: PetscErrorCode TaoGetConvergedReason(Tao tao, TaoConvergedReason *reason)
2375: {
2378: *reason = tao->reason;
2379: return 0;
2380: }
2382: /*@
2383: TaoGetSolutionStatus - Get the current iterate, objective value,
2384: residual, infeasibility, and termination
2386: Not Collective
2388: Input Parameter:
2389: . tao - the Tao context
2391: Output Parameters:
2392: + iterate - the current iterate number (>=0)
2393: . f - the current function value
2394: . gnorm - the square of the gradient norm, duality gap, or other measure indicating distance from optimality.
2395: . cnorm - the infeasibility of the current solution with regard to the constraints.
2396: . xdiff - the step length or trust region radius of the most recent iterate.
2397: - reason - The termination reason, which can equal `TAO_CONTINUE_ITERATING`
2399: Level: intermediate
2401: Notes:
2402: Tao returns the values set by the solvers in the routine `TaoMonitor()`.
2404: If any of the output arguments are set to NULL, no corresponding value will be returned.
2406: .seealso: `TaoMonitor()`, `TaoGetConvergedReason()`
2407: @*/
2408: PetscErrorCode TaoGetSolutionStatus(Tao tao, PetscInt *its, PetscReal *f, PetscReal *gnorm, PetscReal *cnorm, PetscReal *xdiff, TaoConvergedReason *reason)
2409: {
2411: if (its) *its = tao->niter;
2412: if (f) *f = tao->fc;
2413: if (gnorm) *gnorm = tao->residual;
2414: if (cnorm) *cnorm = tao->cnorm;
2415: if (reason) *reason = tao->reason;
2416: if (xdiff) *xdiff = tao->step;
2417: return 0;
2418: }
2420: /*@C
2421: TaoGetType - Gets the current Tao algorithm.
2423: Not Collective
2425: Input Parameter:
2426: . tao - the Tao solver context
2428: Output Parameter:
2429: . type - Tao method
2431: Level: intermediate
2433: .seealso: `Tao`, `TaoType`, `TaoSetType()`
2434: @*/
2435: PetscErrorCode TaoGetType(Tao tao, TaoType *type)
2436: {
2439: *type = ((PetscObject)tao)->type_name;
2440: return 0;
2441: }
2443: /*@C
2444: TaoMonitor - Monitor the solver and the current solution. This
2445: routine will record the iteration number and residual statistics,
2446: call any monitors specified by the user, and calls the convergence-check routine.
2448: Input Parameters:
2449: + tao - the Tao context
2450: . its - the current iterate number (>=0)
2451: . f - the current objective function value
2452: . res - the gradient norm, square root of the duality gap, or other measure indicating distince from optimality. This measure will be recorded and
2453: used for some termination tests.
2454: . cnorm - the infeasibility of the current solution with regard to the constraints.
2455: - steplength - multiple of the step direction added to the previous iterate.
2457: Output Parameters:
2458: . reason - The termination reason, which can equal `TAO_CONTINUE_ITERATING`
2460: Options Database Key:
2461: . -tao_monitor - Use the default monitor, which prints statistics to standard output
2463: Level: developer
2465: .seealso `Tao`, `TaoGetConvergedReason()`, `TaoMonitorDefault()`, `TaoSetMonitor()`
2466: @*/
2467: PetscErrorCode TaoMonitor(Tao tao, PetscInt its, PetscReal f, PetscReal res, PetscReal cnorm, PetscReal steplength)
2468: {
2469: PetscInt i;
2472: tao->fc = f;
2473: tao->residual = res;
2474: tao->cnorm = cnorm;
2475: tao->step = steplength;
2476: if (!its) {
2477: tao->cnorm0 = cnorm;
2478: tao->gnorm0 = res;
2479: }
2481: for (i = 0; i < tao->numbermonitors; i++) (*tao->monitor[i])(tao, tao->monitorcontext[i]);
2482: return 0;
2483: }
2485: /*@
2486: TaoSetConvergenceHistory - Sets the array used to hold the convergence history.
2488: Logically Collective on tao
2490: Input Parameters:
2491: + tao - the Tao solver context
2492: . obj - array to hold objective value history
2493: . resid - array to hold residual history
2494: . cnorm - array to hold constraint violation history
2495: . lits - integer array holds the number of linear iterations for each Tao iteration
2496: . na - size of obj, resid, and cnorm
2497: - reset - `PETSC_TRUE` indicates each new minimization resets the history counter to zero,
2498: else it continues storing new values for new minimizations after the old ones
2500: Notes:
2501: If set, Tao will fill the given arrays with the indicated
2502: information at each iteration. If 'obj','resid','cnorm','lits' are
2503: *all* NULL then space (using size na, or 1000 if na is `PETSC_DECIDE` or
2504: `PETSC_DEFAULT`) is allocated for the history.
2505: If not all are NULL, then only the non-NULL information categories
2506: will be stored, the others will be ignored.
2508: Any convergence information after iteration number 'na' will not be stored.
2510: This routine is useful, e.g., when running a code for purposes
2511: of accurate performance monitoring, when no I/O should be done
2512: during the section of code that is being timed.
2514: Level: intermediate
2516: .seealso: `TaoGetConvergenceHistory()`
2518: @*/
2519: PetscErrorCode TaoSetConvergenceHistory(Tao tao, PetscReal obj[], PetscReal resid[], PetscReal cnorm[], PetscInt lits[], PetscInt na, PetscBool reset)
2520: {
2527: if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000;
2528: if (!obj && !resid && !cnorm && !lits) {
2529: PetscCalloc4(na, &obj, na, &resid, na, &cnorm, na, &lits);
2530: tao->hist_malloc = PETSC_TRUE;
2531: }
2533: tao->hist_obj = obj;
2534: tao->hist_resid = resid;
2535: tao->hist_cnorm = cnorm;
2536: tao->hist_lits = lits;
2537: tao->hist_max = na;
2538: tao->hist_reset = reset;
2539: tao->hist_len = 0;
2540: return 0;
2541: }
2543: /*@C
2544: TaoGetConvergenceHistory - Gets the arrays used that hold the convergence history.
2546: Collective on tao
2548: Input Parameter:
2549: . tao - the Tao context
2551: Output Parameters:
2552: + obj - array used to hold objective value history
2553: . resid - array used to hold residual history
2554: . cnorm - array used to hold constraint violation history
2555: . lits - integer array used to hold linear solver iteration count
2556: - nhist - size of obj, resid, cnorm, and lits
2558: Notes:
2559: This routine must be preceded by calls to `TaoSetConvergenceHistory()`
2560: and `TaoSolve()`, otherwise it returns useless information.
2562: The calling sequence for this routine in Fortran is
2563: $ call TaoGetConvergenceHistory(Tao tao, PetscInt nhist, PetscErrorCode ierr)
2565: This routine is useful, e.g., when running a code for purposes
2566: of accurate performance monitoring, when no I/O should be done
2567: during the section of code that is being timed.
2569: Level: advanced
2571: .seealso: `Tao`, `TaoSolve()`, `TaoSetConvergenceHistory()`
2573: @*/
2574: PetscErrorCode TaoGetConvergenceHistory(Tao tao, PetscReal **obj, PetscReal **resid, PetscReal **cnorm, PetscInt **lits, PetscInt *nhist)
2575: {
2577: if (obj) *obj = tao->hist_obj;
2578: if (cnorm) *cnorm = tao->hist_cnorm;
2579: if (resid) *resid = tao->hist_resid;
2580: if (nhist) *nhist = tao->hist_len;
2581: return 0;
2582: }
2584: /*@
2585: TaoSetApplicationContext - Sets the optional user-defined context for
2586: a solver.
2588: Logically Collective on tao
2590: Input Parameters:
2591: + tao - the Tao context
2592: - usrP - optional user context
2594: Level: intermediate
2596: .seealso: `Tao`, `TaoGetApplicationContext()`, `TaoSetApplicationContext()`
2597: @*/
2598: PetscErrorCode TaoSetApplicationContext(Tao tao, void *usrP)
2599: {
2601: tao->user = usrP;
2602: return 0;
2603: }
2605: /*@
2606: TaoGetApplicationContext - Gets the user-defined context for a
2607: Tao solvers.
2609: Not Collective
2611: Input Parameter:
2612: . tao - Tao context
2614: Output Parameter:
2615: . usrP - user context
2617: Level: intermediate
2619: .seealso: `TaoSetApplicationContext()`
2620: @*/
2621: PetscErrorCode TaoGetApplicationContext(Tao tao, void *usrP)
2622: {
2625: *(void **)usrP = tao->user;
2626: return 0;
2627: }
2629: /*@
2630: TaoSetGradientNorm - Sets the matrix used to define the norm that measures the size of the gradient.
2632: Collective on tao
2634: Input Parameters:
2635: + tao - the Tao context
2636: - M - matrix that defines the norm
2638: Level: beginner
2640: .seealso: `Tao`, `TaoGetGradientNorm()`, `TaoGradientNorm()`
2641: @*/
2642: PetscErrorCode TaoSetGradientNorm(Tao tao, Mat M)
2643: {
2646: PetscObjectReference((PetscObject)M);
2647: MatDestroy(&tao->gradient_norm);
2648: VecDestroy(&tao->gradient_norm_tmp);
2649: tao->gradient_norm = M;
2650: MatCreateVecs(M, NULL, &tao->gradient_norm_tmp);
2651: return 0;
2652: }
2654: /*@
2655: TaoGetGradientNorm - Returns the matrix used to define the norm used for measuring the size of the gradient.
2657: Not Collective
2659: Input Parameter:
2660: . tao - Tao context
2662: Output Parameter:
2663: . M - gradient norm
2665: Level: beginner
2667: .seealso: `Tao`, `TaoSetGradientNorm()`, `TaoGradientNorm()`
2668: @*/
2669: PetscErrorCode TaoGetGradientNorm(Tao tao, Mat *M)
2670: {
2673: *M = tao->gradient_norm;
2674: return 0;
2675: }
2677: /*@C
2678: TaoGradientNorm - Compute the norm with respect to the norm the user has set.
2680: Collective on tao
2682: Input Parameters:
2683: + tao - the Tao context
2684: . gradient - the gradient to be computed
2685: - norm - the norm type
2687: Output Parameter:
2688: . gnorm - the gradient norm
2690: Level: developer
2692: .seealso: `Tao`, `TaoSetGradientNorm()`, `TaoGetGradientNorm()`
2693: @*/
2694: PetscErrorCode TaoGradientNorm(Tao tao, Vec gradient, NormType type, PetscReal *gnorm)
2695: {
2700: if (tao->gradient_norm) {
2701: PetscScalar gnorms;
2704: MatMult(tao->gradient_norm, gradient, tao->gradient_norm_tmp);
2705: VecDot(gradient, tao->gradient_norm_tmp, &gnorms);
2706: *gnorm = PetscRealPart(PetscSqrtScalar(gnorms));
2707: } else {
2708: VecNorm(gradient, type, gnorm);
2709: }
2710: return 0;
2711: }
2713: /*@C
2714: TaoMonitorDrawCtxCreate - Creates the monitor context `TaoMonitorDrawSolution()`
2716: Collective on tao
2718: Output Patameter:
2719: . ctx - the monitor context
2721: Options Database:
2722: . -tao_draw_solution_initial - show initial guess as well as current solution
2724: Level: intermediate
2726: .seealso: `Tao`, `TaoMonitorSet()`, `TaoMonitorDefault()`, `VecView()`, `TaoMonitorDrawCtx()`
2727: @*/
2728: PetscErrorCode TaoMonitorDrawCtxCreate(MPI_Comm comm, const char host[], const char label[], int x, int y, int m, int n, PetscInt howoften, TaoMonitorDrawCtx *ctx)
2729: {
2730: PetscNew(ctx);
2731: PetscViewerDrawOpen(comm, host, label, x, y, m, n, &(*ctx)->viewer);
2732: PetscViewerSetFromOptions((*ctx)->viewer);
2733: (*ctx)->howoften = howoften;
2734: return 0;
2735: }
2737: /*@C
2738: TaoMonitorDrawCtxDestroy - Destroys the monitor context for `TaoMonitorDrawSolution()`
2740: Collective on tao
2742: Input Parameters:
2743: . ctx - the monitor context
2745: Level: intermediate
2747: .seealso: `TaoMonitorSet()`, `TaoMonitorDefault()`, `VecView()`, `TaoMonitorDrawSolution()`
2748: @*/
2749: PetscErrorCode TaoMonitorDrawCtxDestroy(TaoMonitorDrawCtx *ictx)
2750: {
2751: PetscViewerDestroy(&(*ictx)->viewer);
2752: PetscFree(*ictx);
2753: return 0;
2754: }