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