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