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