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