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()`, `TaoView()`, `PetscCtxDestroyFn` 1530 @*/ 1531 PetscErrorCode TaoMonitorSet(Tao tao, PetscErrorCode (*func)(Tao, void *), void *ctx, PetscCtxDestroyFn *dest) 1532 { 1533 PetscFunctionBegin; 1534 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 1535 PetscCheck(tao->numbermonitors < MAXTAOMONITORS, PetscObjectComm((PetscObject)tao), PETSC_ERR_SUP, "Cannot attach another monitor -- max=%d", MAXTAOMONITORS); 1536 for (PetscInt i = 0; i < tao->numbermonitors; i++) { 1537 PetscBool identical; 1538 1539 PetscCall(PetscMonitorCompare((PetscErrorCode (*)(void))(PetscVoidFn *)func, ctx, dest, (PetscErrorCode (*)(void))(PetscVoidFn *)tao->monitor[i], tao->monitorcontext[i], tao->monitordestroy[i], &identical)); 1540 if (identical) PetscFunctionReturn(PETSC_SUCCESS); 1541 } 1542 tao->monitor[tao->numbermonitors] = func; 1543 tao->monitorcontext[tao->numbermonitors] = ctx; 1544 tao->monitordestroy[tao->numbermonitors] = dest; 1545 ++tao->numbermonitors; 1546 PetscFunctionReturn(PETSC_SUCCESS); 1547 } 1548 1549 /*@ 1550 TaoMonitorCancel - Clears all the monitor functions for a `Tao` object. 1551 1552 Logically Collective 1553 1554 Input Parameter: 1555 . tao - the `Tao` solver context 1556 1557 Options Database Key: 1558 . -tao_monitor_cancel - cancels all monitors that have been hardwired 1559 into a code by calls to `TaoMonitorSet()`, but does not cancel those 1560 set via the options database 1561 1562 Level: advanced 1563 1564 Note: 1565 There is no way to clear one specific monitor from a `Tao` object. 1566 1567 .seealso: [](ch_tao), `Tao`, `TaoMonitorDefault()`, `TaoMonitorSet()` 1568 @*/ 1569 PetscErrorCode TaoMonitorCancel(Tao tao) 1570 { 1571 PetscInt i; 1572 1573 PetscFunctionBegin; 1574 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 1575 for (i = 0; i < tao->numbermonitors; i++) { 1576 if (tao->monitordestroy[i]) PetscCall((*tao->monitordestroy[i])(&tao->monitorcontext[i])); 1577 } 1578 tao->numbermonitors = 0; 1579 PetscFunctionReturn(PETSC_SUCCESS); 1580 } 1581 1582 /*@ 1583 TaoMonitorDefault - Default routine for monitoring progress of `TaoSolve()` 1584 1585 Collective 1586 1587 Input Parameters: 1588 + tao - the `Tao` context 1589 - ctx - `PetscViewer` context or `NULL` 1590 1591 Options Database Key: 1592 . -tao_monitor - turn on default monitoring 1593 1594 Level: advanced 1595 1596 Note: 1597 This monitor prints the function value and gradient 1598 norm at each iteration. 1599 1600 .seealso: [](ch_tao), `Tao`, `TaoMonitorDefaultShort()`, `TaoMonitorSet()` 1601 @*/ 1602 PetscErrorCode TaoMonitorDefault(Tao tao, void *ctx) 1603 { 1604 PetscInt its, tabs; 1605 PetscReal fct, gnorm; 1606 PetscViewer viewer = (PetscViewer)ctx; 1607 1608 PetscFunctionBegin; 1609 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 1610 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1611 its = tao->niter; 1612 fct = tao->fc; 1613 gnorm = tao->residual; 1614 PetscCall(PetscViewerASCIIGetTab(viewer, &tabs)); 1615 PetscCall(PetscViewerASCIISetTab(viewer, ((PetscObject)tao)->tablevel)); 1616 if (its == 0 && ((PetscObject)tao)->prefix && !tao->header_printed) { 1617 PetscCall(PetscViewerASCIIPrintf(viewer, " Iteration information for %s solve.\n", ((PetscObject)tao)->prefix)); 1618 tao->header_printed = PETSC_TRUE; 1619 } 1620 PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " TAO,", its)); 1621 PetscCall(PetscViewerASCIIPrintf(viewer, " Function value: %g,", (double)fct)); 1622 if (gnorm >= PETSC_INFINITY) { 1623 PetscCall(PetscViewerASCIIPrintf(viewer, " Residual: Inf \n")); 1624 } else { 1625 PetscCall(PetscViewerASCIIPrintf(viewer, " Residual: %g \n", (double)gnorm)); 1626 } 1627 PetscCall(PetscViewerASCIISetTab(viewer, tabs)); 1628 PetscFunctionReturn(PETSC_SUCCESS); 1629 } 1630 1631 /*@ 1632 TaoMonitorGlobalization - Default routine for monitoring progress of `TaoSolve()` with extra detail on the globalization method. 1633 1634 Collective 1635 1636 Input Parameters: 1637 + tao - the `Tao` context 1638 - ctx - `PetscViewer` context or `NULL` 1639 1640 Options Database Key: 1641 . -tao_monitor_globalization - turn on monitoring with globalization information 1642 1643 Level: advanced 1644 1645 Note: 1646 This monitor prints the function value and gradient norm at each 1647 iteration, as well as the step size and trust radius. Note that the 1648 step size and trust radius may be the same for some algorithms. 1649 1650 .seealso: [](ch_tao), `Tao`, `TaoMonitorDefaultShort()`, `TaoMonitorSet()` 1651 @*/ 1652 PetscErrorCode TaoMonitorGlobalization(Tao tao, void *ctx) 1653 { 1654 PetscInt its, tabs; 1655 PetscReal fct, gnorm, stp, tr; 1656 PetscViewer viewer = (PetscViewer)ctx; 1657 1658 PetscFunctionBegin; 1659 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 1660 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1661 its = tao->niter; 1662 fct = tao->fc; 1663 gnorm = tao->residual; 1664 stp = tao->step; 1665 tr = tao->trust; 1666 PetscCall(PetscViewerASCIIGetTab(viewer, &tabs)); 1667 PetscCall(PetscViewerASCIISetTab(viewer, ((PetscObject)tao)->tablevel)); 1668 if (its == 0 && ((PetscObject)tao)->prefix && !tao->header_printed) { 1669 PetscCall(PetscViewerASCIIPrintf(viewer, " Iteration information for %s solve.\n", ((PetscObject)tao)->prefix)); 1670 tao->header_printed = PETSC_TRUE; 1671 } 1672 PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " TAO,", its)); 1673 PetscCall(PetscViewerASCIIPrintf(viewer, " Function value: %g,", (double)fct)); 1674 if (gnorm >= PETSC_INFINITY) { 1675 PetscCall(PetscViewerASCIIPrintf(viewer, " Residual: Inf,")); 1676 } else { 1677 PetscCall(PetscViewerASCIIPrintf(viewer, " Residual: %g,", (double)gnorm)); 1678 } 1679 PetscCall(PetscViewerASCIIPrintf(viewer, " Step: %g, Trust: %g\n", (double)stp, (double)tr)); 1680 PetscCall(PetscViewerASCIISetTab(viewer, tabs)); 1681 PetscFunctionReturn(PETSC_SUCCESS); 1682 } 1683 1684 /*@ 1685 TaoMonitorDefaultShort - Routine for monitoring progress of `TaoSolve()` that displays fewer digits than `TaoMonitorDefault()` 1686 1687 Collective 1688 1689 Input Parameters: 1690 + tao - the `Tao` context 1691 - ctx - `PetscViewer` context of type `PETSCVIEWERASCII` 1692 1693 Options Database Key: 1694 . -tao_monitor_short - turn on default short monitoring 1695 1696 Level: advanced 1697 1698 Note: 1699 Same as `TaoMonitorDefault()` except 1700 it prints fewer digits of the residual as the residual gets smaller. 1701 This is because the later digits are meaningless and are often 1702 different on different machines; by using this routine different 1703 machines will usually generate the same output. 1704 1705 .seealso: [](ch_tao), `Tao`, `TaoMonitorDefault()`, `TaoMonitorSet()` 1706 @*/ 1707 PetscErrorCode TaoMonitorDefaultShort(Tao tao, void *ctx) 1708 { 1709 PetscInt its, tabs; 1710 PetscReal fct, gnorm; 1711 PetscViewer viewer = (PetscViewer)ctx; 1712 1713 PetscFunctionBegin; 1714 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 1715 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1716 its = tao->niter; 1717 fct = tao->fc; 1718 gnorm = tao->residual; 1719 PetscCall(PetscViewerASCIIGetTab(viewer, &tabs)); 1720 PetscCall(PetscViewerASCIISetTab(viewer, ((PetscObject)tao)->tablevel)); 1721 PetscCall(PetscViewerASCIIPrintf(viewer, "iter = %3" PetscInt_FMT ",", its)); 1722 PetscCall(PetscViewerASCIIPrintf(viewer, " Function value %g,", (double)fct)); 1723 if (gnorm >= PETSC_INFINITY) { 1724 PetscCall(PetscViewerASCIIPrintf(viewer, " Residual: Inf \n")); 1725 } else if (gnorm > 1.e-6) { 1726 PetscCall(PetscViewerASCIIPrintf(viewer, " Residual: %g \n", (double)gnorm)); 1727 } else if (gnorm > 1.e-11) { 1728 PetscCall(PetscViewerASCIIPrintf(viewer, " Residual: < 1.0e-6 \n")); 1729 } else { 1730 PetscCall(PetscViewerASCIIPrintf(viewer, " Residual: < 1.0e-11 \n")); 1731 } 1732 PetscCall(PetscViewerASCIISetTab(viewer, tabs)); 1733 PetscFunctionReturn(PETSC_SUCCESS); 1734 } 1735 1736 /*@ 1737 TaoMonitorConstraintNorm - same as `TaoMonitorDefault()` except 1738 it prints the norm of the constraint function. 1739 1740 Collective 1741 1742 Input Parameters: 1743 + tao - the `Tao` context 1744 - ctx - `PetscViewer` context or `NULL` 1745 1746 Options Database Key: 1747 . -tao_monitor_constraint_norm - monitor the constraints 1748 1749 Level: advanced 1750 1751 .seealso: [](ch_tao), `Tao`, `TaoMonitorDefault()`, `TaoMonitorSet()` 1752 @*/ 1753 PetscErrorCode TaoMonitorConstraintNorm(Tao tao, void *ctx) 1754 { 1755 PetscInt its, tabs; 1756 PetscReal fct, gnorm; 1757 PetscViewer viewer = (PetscViewer)ctx; 1758 1759 PetscFunctionBegin; 1760 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 1761 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1762 its = tao->niter; 1763 fct = tao->fc; 1764 gnorm = tao->residual; 1765 PetscCall(PetscViewerASCIIGetTab(viewer, &tabs)); 1766 PetscCall(PetscViewerASCIISetTab(viewer, ((PetscObject)tao)->tablevel)); 1767 PetscCall(PetscViewerASCIIPrintf(viewer, "iter = %" PetscInt_FMT ",", its)); 1768 PetscCall(PetscViewerASCIIPrintf(viewer, " Function value: %g,", (double)fct)); 1769 PetscCall(PetscViewerASCIIPrintf(viewer, " Residual: %g ", (double)gnorm)); 1770 PetscCall(PetscViewerASCIIPrintf(viewer, " Constraint: %g \n", (double)tao->cnorm)); 1771 PetscCall(PetscViewerASCIISetTab(viewer, tabs)); 1772 PetscFunctionReturn(PETSC_SUCCESS); 1773 } 1774 1775 /*@C 1776 TaoMonitorSolution - Views the solution at each iteration of `TaoSolve()` 1777 1778 Collective 1779 1780 Input Parameters: 1781 + tao - the `Tao` context 1782 - ctx - `PetscViewer` context or `NULL` 1783 1784 Options Database Key: 1785 . -tao_monitor_solution - view the solution 1786 1787 Level: advanced 1788 1789 .seealso: [](ch_tao), `Tao`, `TaoMonitorDefaultShort()`, `TaoMonitorSet()` 1790 @*/ 1791 PetscErrorCode TaoMonitorSolution(Tao tao, void *ctx) 1792 { 1793 PetscViewer viewer = (PetscViewer)ctx; 1794 1795 PetscFunctionBegin; 1796 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 1797 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1798 PetscCall(VecView(tao->solution, viewer)); 1799 PetscFunctionReturn(PETSC_SUCCESS); 1800 } 1801 1802 /*@C 1803 TaoMonitorGradient - Views the gradient at each iteration of `TaoSolve()` 1804 1805 Collective 1806 1807 Input Parameters: 1808 + tao - the `Tao` context 1809 - ctx - `PetscViewer` context or `NULL` 1810 1811 Options Database Key: 1812 . -tao_monitor_gradient - view the gradient at each iteration 1813 1814 Level: advanced 1815 1816 .seealso: [](ch_tao), `Tao`, `TaoMonitorDefaultShort()`, `TaoMonitorSet()` 1817 @*/ 1818 PetscErrorCode TaoMonitorGradient(Tao tao, void *ctx) 1819 { 1820 PetscViewer viewer = (PetscViewer)ctx; 1821 1822 PetscFunctionBegin; 1823 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 1824 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1825 PetscCall(VecView(tao->gradient, viewer)); 1826 PetscFunctionReturn(PETSC_SUCCESS); 1827 } 1828 1829 /*@C 1830 TaoMonitorStep - Views the step-direction at each iteration of `TaoSolve()` 1831 1832 Collective 1833 1834 Input Parameters: 1835 + tao - the `Tao` context 1836 - ctx - `PetscViewer` context or `NULL` 1837 1838 Options Database Key: 1839 . -tao_monitor_step - view the step vector at each iteration 1840 1841 Level: advanced 1842 1843 .seealso: [](ch_tao), `Tao`, `TaoMonitorDefaultShort()`, `TaoMonitorSet()` 1844 @*/ 1845 PetscErrorCode TaoMonitorStep(Tao tao, void *ctx) 1846 { 1847 PetscViewer viewer = (PetscViewer)ctx; 1848 1849 PetscFunctionBegin; 1850 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 1851 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1852 PetscCall(VecView(tao->stepdirection, viewer)); 1853 PetscFunctionReturn(PETSC_SUCCESS); 1854 } 1855 1856 /*@C 1857 TaoMonitorSolutionDraw - Plots the solution at each iteration of `TaoSolve()` 1858 1859 Collective 1860 1861 Input Parameters: 1862 + tao - the `Tao` context 1863 - ctx - `TaoMonitorDraw` context 1864 1865 Options Database Key: 1866 . -tao_monitor_solution_draw - draw the solution at each iteration 1867 1868 Level: advanced 1869 1870 Note: 1871 The context created by `TaoMonitorDrawCtxCreate()`, along with `TaoMonitorSolutionDraw()`, and `TaoMonitorDrawCtxDestroy()` 1872 are passed to `TaoMonitorSet()` to monitor the solution graphically. 1873 1874 .seealso: [](ch_tao), `Tao`, `TaoMonitorSolution()`, `TaoMonitorSet()`, `TaoMonitorGradientDraw()`, `TaoMonitorDrawCtxCreate()`, 1875 `TaoMonitorDrawCtxDestroy()` 1876 @*/ 1877 PetscErrorCode TaoMonitorSolutionDraw(Tao tao, void *ctx) 1878 { 1879 TaoMonitorDrawCtx ictx = (TaoMonitorDrawCtx)ctx; 1880 1881 PetscFunctionBegin; 1882 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 1883 if (!(((ictx->howoften > 0) && (!(tao->niter % ictx->howoften))) || ((ictx->howoften == -1) && tao->reason))) PetscFunctionReturn(PETSC_SUCCESS); 1884 PetscCall(VecView(tao->solution, ictx->viewer)); 1885 PetscFunctionReturn(PETSC_SUCCESS); 1886 } 1887 1888 /*@C 1889 TaoMonitorGradientDraw - Plots the gradient at each iteration of `TaoSolve()` 1890 1891 Collective 1892 1893 Input Parameters: 1894 + tao - the `Tao` context 1895 - ctx - `PetscViewer` context 1896 1897 Options Database Key: 1898 . -tao_monitor_gradient_draw - draw the gradient at each iteration 1899 1900 Level: advanced 1901 1902 .seealso: [](ch_tao), `Tao`, `TaoMonitorGradient()`, `TaoMonitorSet()`, `TaoMonitorSolutionDraw()` 1903 @*/ 1904 PetscErrorCode TaoMonitorGradientDraw(Tao tao, void *ctx) 1905 { 1906 TaoMonitorDrawCtx ictx = (TaoMonitorDrawCtx)ctx; 1907 1908 PetscFunctionBegin; 1909 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 1910 if (!(((ictx->howoften > 0) && (!(tao->niter % ictx->howoften))) || ((ictx->howoften == -1) && tao->reason))) PetscFunctionReturn(PETSC_SUCCESS); 1911 PetscCall(VecView(tao->gradient, ictx->viewer)); 1912 PetscFunctionReturn(PETSC_SUCCESS); 1913 } 1914 1915 /*@C 1916 TaoMonitorStepDraw - Plots the step direction at each iteration of `TaoSolve()` 1917 1918 Collective 1919 1920 Input Parameters: 1921 + tao - the `Tao` context 1922 - ctx - the `PetscViewer` context 1923 1924 Options Database Key: 1925 . -tao_monitor_step_draw - draw the step direction at each iteration 1926 1927 Level: advanced 1928 1929 .seealso: [](ch_tao), `Tao`, `TaoMonitorSet()`, `TaoMonitorSolutionDraw` 1930 @*/ 1931 PetscErrorCode TaoMonitorStepDraw(Tao tao, void *ctx) 1932 { 1933 PetscViewer viewer = (PetscViewer)ctx; 1934 1935 PetscFunctionBegin; 1936 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 1937 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1938 PetscCall(VecView(tao->stepdirection, viewer)); 1939 PetscFunctionReturn(PETSC_SUCCESS); 1940 } 1941 1942 /*@C 1943 TaoMonitorResidual - Views the least-squares residual at each iteration of `TaoSolve()` 1944 1945 Collective 1946 1947 Input Parameters: 1948 + tao - the `Tao` context 1949 - ctx - the `PetscViewer` context or `NULL` 1950 1951 Options Database Key: 1952 . -tao_monitor_ls_residual - view the residual at each iteration 1953 1954 Level: advanced 1955 1956 .seealso: [](ch_tao), `Tao`, `TaoMonitorDefaultShort()`, `TaoMonitorSet()` 1957 @*/ 1958 PetscErrorCode TaoMonitorResidual(Tao tao, void *ctx) 1959 { 1960 PetscViewer viewer = (PetscViewer)ctx; 1961 1962 PetscFunctionBegin; 1963 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 1964 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1965 PetscCall(VecView(tao->ls_res, viewer)); 1966 PetscFunctionReturn(PETSC_SUCCESS); 1967 } 1968 1969 /*@ 1970 TaoDefaultConvergenceTest - Determines whether the solver should continue iterating 1971 or terminate. 1972 1973 Collective 1974 1975 Input Parameters: 1976 + tao - the `Tao` context 1977 - dummy - unused dummy context 1978 1979 Level: developer 1980 1981 Notes: 1982 This routine checks the residual in the optimality conditions, the 1983 relative residual in the optimity conditions, the number of function 1984 evaluations, and the function value to test convergence. Some 1985 solvers may use different convergence routines. 1986 1987 .seealso: [](ch_tao), `Tao`, `TaoSetTolerances()`, `TaoGetConvergedReason()`, `TaoSetConvergedReason()` 1988 @*/ 1989 PetscErrorCode TaoDefaultConvergenceTest(Tao tao, void *dummy) 1990 { 1991 PetscInt niter = tao->niter, nfuncs = PetscMax(tao->nfuncs, tao->nfuncgrads); 1992 PetscInt max_funcs = tao->max_funcs; 1993 PetscReal gnorm = tao->residual, gnorm0 = tao->gnorm0; 1994 PetscReal f = tao->fc, steptol = tao->steptol, trradius = tao->step; 1995 PetscReal gatol = tao->gatol, grtol = tao->grtol, gttol = tao->gttol; 1996 PetscReal catol = tao->catol, crtol = tao->crtol; 1997 PetscReal fmin = tao->fmin, cnorm = tao->cnorm; 1998 TaoConvergedReason reason = tao->reason; 1999 2000 PetscFunctionBegin; 2001 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 2002 if (reason != TAO_CONTINUE_ITERATING) PetscFunctionReturn(PETSC_SUCCESS); 2003 2004 if (PetscIsInfOrNanReal(f)) { 2005 PetscCall(PetscInfo(tao, "Failed to converged, function value is Inf or NaN\n")); 2006 reason = TAO_DIVERGED_NAN; 2007 } else if (f <= fmin && cnorm <= catol) { 2008 PetscCall(PetscInfo(tao, "Converged due to function value %g < minimum function value %g\n", (double)f, (double)fmin)); 2009 reason = TAO_CONVERGED_MINF; 2010 } else if (gnorm <= gatol && cnorm <= catol) { 2011 PetscCall(PetscInfo(tao, "Converged due to residual norm ||g(X)||=%g < %g\n", (double)gnorm, (double)gatol)); 2012 reason = TAO_CONVERGED_GATOL; 2013 } else if (f != 0 && PetscAbsReal(gnorm / f) <= grtol && cnorm <= crtol) { 2014 PetscCall(PetscInfo(tao, "Converged due to residual ||g(X)||/|f(X)| =%g < %g\n", (double)(gnorm / f), (double)grtol)); 2015 reason = TAO_CONVERGED_GRTOL; 2016 } else if (gnorm0 != 0 && ((gttol == 0 && gnorm == 0) || gnorm / gnorm0 < gttol) && cnorm <= crtol) { 2017 PetscCall(PetscInfo(tao, "Converged due to relative residual norm ||g(X)||/||g(X0)|| = %g < %g\n", (double)(gnorm / gnorm0), (double)gttol)); 2018 reason = TAO_CONVERGED_GTTOL; 2019 } else if (max_funcs != PETSC_UNLIMITED && nfuncs > max_funcs) { 2020 PetscCall(PetscInfo(tao, "Exceeded maximum number of function evaluations: %" PetscInt_FMT " > %" PetscInt_FMT "\n", nfuncs, max_funcs)); 2021 reason = TAO_DIVERGED_MAXFCN; 2022 } else if (tao->lsflag != 0) { 2023 PetscCall(PetscInfo(tao, "Tao Line Search failure.\n")); 2024 reason = TAO_DIVERGED_LS_FAILURE; 2025 } else if (trradius < steptol && niter > 0) { 2026 PetscCall(PetscInfo(tao, "Trust region/step size too small: %g < %g\n", (double)trradius, (double)steptol)); 2027 reason = TAO_CONVERGED_STEPTOL; 2028 } else if (niter >= tao->max_it) { 2029 PetscCall(PetscInfo(tao, "Exceeded maximum number of iterations: %" PetscInt_FMT " > %" PetscInt_FMT "\n", niter, tao->max_it)); 2030 reason = TAO_DIVERGED_MAXITS; 2031 } else { 2032 reason = TAO_CONTINUE_ITERATING; 2033 } 2034 tao->reason = reason; 2035 PetscFunctionReturn(PETSC_SUCCESS); 2036 } 2037 2038 /*@ 2039 TaoSetOptionsPrefix - Sets the prefix used for searching for all 2040 Tao options in the database. 2041 2042 Logically Collective 2043 2044 Input Parameters: 2045 + tao - the `Tao` context 2046 - p - the prefix string to prepend to all Tao option requests 2047 2048 Level: advanced 2049 2050 Notes: 2051 A hyphen (-) must NOT be given at the beginning of the prefix name. 2052 The first character of all runtime options is AUTOMATICALLY the hyphen. 2053 2054 For example, to distinguish between the runtime options for two 2055 different Tao solvers, one could call 2056 .vb 2057 TaoSetOptionsPrefix(tao1,"sys1_") 2058 TaoSetOptionsPrefix(tao2,"sys2_") 2059 .ve 2060 2061 This would enable use of different options for each system, such as 2062 .vb 2063 -sys1_tao_method blmvm -sys1_tao_grtol 1.e-3 2064 -sys2_tao_method lmvm -sys2_tao_grtol 1.e-4 2065 .ve 2066 2067 .seealso: [](ch_tao), `Tao`, `TaoSetFromOptions()`, `TaoAppendOptionsPrefix()`, `TaoGetOptionsPrefix()` 2068 @*/ 2069 PetscErrorCode TaoSetOptionsPrefix(Tao tao, const char p[]) 2070 { 2071 PetscFunctionBegin; 2072 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 2073 PetscCall(PetscObjectSetOptionsPrefix((PetscObject)tao, p)); 2074 if (tao->linesearch) PetscCall(TaoLineSearchSetOptionsPrefix(tao->linesearch, p)); 2075 if (tao->ksp) PetscCall(KSPSetOptionsPrefix(tao->ksp, p)); 2076 PetscFunctionReturn(PETSC_SUCCESS); 2077 } 2078 2079 /*@ 2080 TaoAppendOptionsPrefix - Appends to the prefix used for searching for all Tao options in the database. 2081 2082 Logically Collective 2083 2084 Input Parameters: 2085 + tao - the `Tao` solver context 2086 - p - the prefix string to prepend to all `Tao` option requests 2087 2088 Level: advanced 2089 2090 Note: 2091 A hyphen (-) must NOT be given at the beginning of the prefix name. 2092 The first character of all runtime options is automatically the hyphen. 2093 2094 .seealso: [](ch_tao), `Tao`, `TaoSetFromOptions()`, `TaoSetOptionsPrefix()`, `TaoGetOptionsPrefix()` 2095 @*/ 2096 PetscErrorCode TaoAppendOptionsPrefix(Tao tao, const char p[]) 2097 { 2098 PetscFunctionBegin; 2099 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 2100 PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)tao, p)); 2101 if (tao->linesearch) PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)tao->linesearch, p)); 2102 if (tao->ksp) PetscCall(KSPAppendOptionsPrefix(tao->ksp, p)); 2103 PetscFunctionReturn(PETSC_SUCCESS); 2104 } 2105 2106 /*@ 2107 TaoGetOptionsPrefix - Gets the prefix used for searching for all 2108 Tao options in the database 2109 2110 Not Collective 2111 2112 Input Parameter: 2113 . tao - the `Tao` context 2114 2115 Output Parameter: 2116 . p - pointer to the prefix string used is returned 2117 2118 Level: advanced 2119 2120 .seealso: [](ch_tao), `Tao`, `TaoSetFromOptions()`, `TaoSetOptionsPrefix()`, `TaoAppendOptionsPrefix()` 2121 @*/ 2122 PetscErrorCode TaoGetOptionsPrefix(Tao tao, const char *p[]) 2123 { 2124 PetscFunctionBegin; 2125 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 2126 PetscCall(PetscObjectGetOptionsPrefix((PetscObject)tao, p)); 2127 PetscFunctionReturn(PETSC_SUCCESS); 2128 } 2129 2130 /*@ 2131 TaoSetType - Sets the `TaoType` for the minimization solver. 2132 2133 Collective 2134 2135 Input Parameters: 2136 + tao - the `Tao` solver context 2137 - type - a known method 2138 2139 Options Database Key: 2140 . -tao_type <type> - Sets the method; use -help for a list 2141 of available methods (for instance, "-tao_type lmvm" or "-tao_type tron") 2142 2143 Level: intermediate 2144 2145 .seealso: [](ch_tao), `Tao`, `TaoCreate()`, `TaoGetType()`, `TaoType` 2146 @*/ 2147 PetscErrorCode TaoSetType(Tao tao, TaoType type) 2148 { 2149 PetscErrorCode (*create_xxx)(Tao); 2150 PetscBool issame; 2151 2152 PetscFunctionBegin; 2153 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 2154 2155 PetscCall(PetscObjectTypeCompare((PetscObject)tao, type, &issame)); 2156 if (issame) PetscFunctionReturn(PETSC_SUCCESS); 2157 2158 PetscCall(PetscFunctionListFind(TaoList, type, &create_xxx)); 2159 PetscCheck(create_xxx, PetscObjectComm((PetscObject)tao), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unable to find requested Tao type %s", type); 2160 2161 /* Destroy the existing solver information */ 2162 PetscTryTypeMethod(tao, destroy); 2163 PetscCall(KSPDestroy(&tao->ksp)); 2164 PetscCall(TaoLineSearchDestroy(&tao->linesearch)); 2165 2166 /* Reinitialize type-specific function pointers in TaoOps structure */ 2167 tao->ops->setup = NULL; 2168 tao->ops->computedual = NULL; 2169 tao->ops->solve = NULL; 2170 tao->ops->view = NULL; 2171 tao->ops->setfromoptions = NULL; 2172 tao->ops->destroy = NULL; 2173 2174 tao->setupcalled = PETSC_FALSE; 2175 2176 PetscCall((*create_xxx)(tao)); 2177 PetscCall(PetscObjectChangeTypeName((PetscObject)tao, type)); 2178 PetscFunctionReturn(PETSC_SUCCESS); 2179 } 2180 2181 /*@C 2182 TaoRegister - Adds a method to the Tao package for minimization. 2183 2184 Not Collective, No Fortran Support 2185 2186 Input Parameters: 2187 + sname - name of a new user-defined solver 2188 - func - routine to Create method context 2189 2190 Example Usage: 2191 .vb 2192 TaoRegister("my_solver", MySolverCreate); 2193 .ve 2194 2195 Then, your solver can be chosen with the procedural interface via 2196 .vb 2197 TaoSetType(tao, "my_solver") 2198 .ve 2199 or at runtime via the option 2200 .vb 2201 -tao_type my_solver 2202 .ve 2203 2204 Level: advanced 2205 2206 Note: 2207 `TaoRegister()` may be called multiple times to add several user-defined solvers. 2208 2209 .seealso: [](ch_tao), `Tao`, `TaoSetType()`, `TaoRegisterAll()`, `TaoRegisterDestroy()` 2210 @*/ 2211 PetscErrorCode TaoRegister(const char sname[], PetscErrorCode (*func)(Tao)) 2212 { 2213 PetscFunctionBegin; 2214 PetscCall(TaoInitializePackage()); 2215 PetscCall(PetscFunctionListAdd(&TaoList, sname, func)); 2216 PetscFunctionReturn(PETSC_SUCCESS); 2217 } 2218 2219 /*@C 2220 TaoRegisterDestroy - Frees the list of minimization solvers that were 2221 registered by `TaoRegister()`. 2222 2223 Not Collective 2224 2225 Level: advanced 2226 2227 .seealso: [](ch_tao), `Tao`, `TaoRegisterAll()`, `TaoRegister()` 2228 @*/ 2229 PetscErrorCode TaoRegisterDestroy(void) 2230 { 2231 PetscFunctionBegin; 2232 PetscCall(PetscFunctionListDestroy(&TaoList)); 2233 TaoRegisterAllCalled = PETSC_FALSE; 2234 PetscFunctionReturn(PETSC_SUCCESS); 2235 } 2236 2237 /*@ 2238 TaoGetIterationNumber - Gets the number of `TaoSolve()` iterations completed 2239 at this time. 2240 2241 Not Collective 2242 2243 Input Parameter: 2244 . tao - the `Tao` context 2245 2246 Output Parameter: 2247 . iter - iteration number 2248 2249 Notes: 2250 For example, during the computation of iteration 2 this would return 1. 2251 2252 Level: intermediate 2253 2254 .seealso: [](ch_tao), `Tao`, `TaoGetLinearSolveIterations()`, `TaoGetResidualNorm()`, `TaoGetObjective()` 2255 @*/ 2256 PetscErrorCode TaoGetIterationNumber(Tao tao, PetscInt *iter) 2257 { 2258 PetscFunctionBegin; 2259 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 2260 PetscAssertPointer(iter, 2); 2261 *iter = tao->niter; 2262 PetscFunctionReturn(PETSC_SUCCESS); 2263 } 2264 2265 /*@ 2266 TaoGetResidualNorm - Gets the current value of the norm of the residual (gradient) 2267 at this time. 2268 2269 Not Collective 2270 2271 Input Parameter: 2272 . tao - the `Tao` context 2273 2274 Output Parameter: 2275 . value - the current value 2276 2277 Level: intermediate 2278 2279 Developer Notes: 2280 This is the 2-norm of the residual, we cannot use `TaoGetGradientNorm()` because that has 2281 a different meaning. For some reason `Tao` sometimes calls the gradient the residual. 2282 2283 .seealso: [](ch_tao), `Tao`, `TaoGetLinearSolveIterations()`, `TaoGetIterationNumber()`, `TaoGetObjective()` 2284 @*/ 2285 PetscErrorCode TaoGetResidualNorm(Tao tao, PetscReal *value) 2286 { 2287 PetscFunctionBegin; 2288 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 2289 PetscAssertPointer(value, 2); 2290 *value = tao->residual; 2291 PetscFunctionReturn(PETSC_SUCCESS); 2292 } 2293 2294 /*@ 2295 TaoSetIterationNumber - Sets the current iteration number. 2296 2297 Logically Collective 2298 2299 Input Parameters: 2300 + tao - the `Tao` context 2301 - iter - iteration number 2302 2303 Level: developer 2304 2305 .seealso: [](ch_tao), `Tao`, `TaoGetLinearSolveIterations()` 2306 @*/ 2307 PetscErrorCode TaoSetIterationNumber(Tao tao, PetscInt iter) 2308 { 2309 PetscFunctionBegin; 2310 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 2311 PetscValidLogicalCollectiveInt(tao, iter, 2); 2312 PetscCall(PetscObjectSAWsTakeAccess((PetscObject)tao)); 2313 tao->niter = iter; 2314 PetscCall(PetscObjectSAWsGrantAccess((PetscObject)tao)); 2315 PetscFunctionReturn(PETSC_SUCCESS); 2316 } 2317 2318 /*@ 2319 TaoGetTotalIterationNumber - Gets the total number of `TaoSolve()` iterations 2320 completed. This number keeps accumulating if multiple solves 2321 are called with the `Tao` object. 2322 2323 Not Collective 2324 2325 Input Parameter: 2326 . tao - the `Tao` context 2327 2328 Output Parameter: 2329 . iter - number of iterations 2330 2331 Level: intermediate 2332 2333 Note: 2334 The total iteration count is updated after each solve, if there is a current 2335 `TaoSolve()` in progress then those iterations are not included in the count 2336 2337 .seealso: [](ch_tao), `Tao`, `TaoGetLinearSolveIterations()` 2338 @*/ 2339 PetscErrorCode TaoGetTotalIterationNumber(Tao tao, PetscInt *iter) 2340 { 2341 PetscFunctionBegin; 2342 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 2343 PetscAssertPointer(iter, 2); 2344 *iter = tao->ntotalits; 2345 PetscFunctionReturn(PETSC_SUCCESS); 2346 } 2347 2348 /*@ 2349 TaoSetTotalIterationNumber - Sets the current total iteration number. 2350 2351 Logically Collective 2352 2353 Input Parameters: 2354 + tao - the `Tao` context 2355 - iter - the iteration number 2356 2357 Level: developer 2358 2359 .seealso: [](ch_tao), `Tao`, `TaoGetLinearSolveIterations()` 2360 @*/ 2361 PetscErrorCode TaoSetTotalIterationNumber(Tao tao, PetscInt iter) 2362 { 2363 PetscFunctionBegin; 2364 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 2365 PetscValidLogicalCollectiveInt(tao, iter, 2); 2366 PetscCall(PetscObjectSAWsTakeAccess((PetscObject)tao)); 2367 tao->ntotalits = iter; 2368 PetscCall(PetscObjectSAWsGrantAccess((PetscObject)tao)); 2369 PetscFunctionReturn(PETSC_SUCCESS); 2370 } 2371 2372 /*@ 2373 TaoSetConvergedReason - Sets the termination flag on a `Tao` object 2374 2375 Logically Collective 2376 2377 Input Parameters: 2378 + tao - the `Tao` context 2379 - reason - the `TaoConvergedReason` 2380 2381 Level: intermediate 2382 2383 .seealso: [](ch_tao), `Tao`, `TaoConvergedReason` 2384 @*/ 2385 PetscErrorCode TaoSetConvergedReason(Tao tao, TaoConvergedReason reason) 2386 { 2387 PetscFunctionBegin; 2388 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 2389 PetscValidLogicalCollectiveEnum(tao, reason, 2); 2390 tao->reason = reason; 2391 PetscFunctionReturn(PETSC_SUCCESS); 2392 } 2393 2394 /*@ 2395 TaoGetConvergedReason - Gets the reason the `TaoSolve()` was stopped. 2396 2397 Not Collective 2398 2399 Input Parameter: 2400 . tao - the `Tao` solver context 2401 2402 Output Parameter: 2403 . reason - value of `TaoConvergedReason` 2404 2405 Level: intermediate 2406 2407 .seealso: [](ch_tao), `Tao`, `TaoConvergedReason`, `TaoSetConvergenceTest()`, `TaoSetTolerances()` 2408 @*/ 2409 PetscErrorCode TaoGetConvergedReason(Tao tao, TaoConvergedReason *reason) 2410 { 2411 PetscFunctionBegin; 2412 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 2413 PetscAssertPointer(reason, 2); 2414 *reason = tao->reason; 2415 PetscFunctionReturn(PETSC_SUCCESS); 2416 } 2417 2418 /*@ 2419 TaoGetSolutionStatus - Get the current iterate, objective value, 2420 residual, infeasibility, and termination from a `Tao` object 2421 2422 Not Collective 2423 2424 Input Parameter: 2425 . tao - the `Tao` context 2426 2427 Output Parameters: 2428 + its - the current iterate number (>=0) 2429 . f - the current function value 2430 . gnorm - the square of the gradient norm, duality gap, or other measure indicating distance from optimality. 2431 . cnorm - the infeasibility of the current solution with regard to the constraints. 2432 . xdiff - the step length or trust region radius of the most recent iterate. 2433 - reason - The termination reason, which can equal `TAO_CONTINUE_ITERATING` 2434 2435 Level: intermediate 2436 2437 Notes: 2438 Tao returns the values set by the solvers in the routine `TaoMonitor()`. 2439 2440 If any of the output arguments are set to `NULL`, no corresponding value will be returned. 2441 2442 .seealso: [](ch_tao), `TaoMonitor()`, `TaoGetConvergedReason()` 2443 @*/ 2444 PetscErrorCode TaoGetSolutionStatus(Tao tao, PetscInt *its, PetscReal *f, PetscReal *gnorm, PetscReal *cnorm, PetscReal *xdiff, TaoConvergedReason *reason) 2445 { 2446 PetscFunctionBegin; 2447 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 2448 if (its) *its = tao->niter; 2449 if (f) *f = tao->fc; 2450 if (gnorm) *gnorm = tao->residual; 2451 if (cnorm) *cnorm = tao->cnorm; 2452 if (reason) *reason = tao->reason; 2453 if (xdiff) *xdiff = tao->step; 2454 PetscFunctionReturn(PETSC_SUCCESS); 2455 } 2456 2457 /*@ 2458 TaoGetType - Gets the current `TaoType` being used in the `Tao` object 2459 2460 Not Collective 2461 2462 Input Parameter: 2463 . tao - the `Tao` solver context 2464 2465 Output Parameter: 2466 . type - the `TaoType` 2467 2468 Level: intermediate 2469 2470 .seealso: [](ch_tao), `Tao`, `TaoType`, `TaoSetType()` 2471 @*/ 2472 PetscErrorCode TaoGetType(Tao tao, TaoType *type) 2473 { 2474 PetscFunctionBegin; 2475 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 2476 PetscAssertPointer(type, 2); 2477 *type = ((PetscObject)tao)->type_name; 2478 PetscFunctionReturn(PETSC_SUCCESS); 2479 } 2480 2481 /*@C 2482 TaoMonitor - Monitor the solver and the current solution. This 2483 routine will record the iteration number and residual statistics, 2484 and call any monitors specified by the user. 2485 2486 Input Parameters: 2487 + tao - the `Tao` context 2488 . its - the current iterate number (>=0) 2489 . f - the current objective function value 2490 . res - the gradient norm, square root of the duality gap, or other measure indicating distance from optimality. This measure will be recorded and 2491 used for some termination tests. 2492 . cnorm - the infeasibility of the current solution with regard to the constraints. 2493 - steplength - multiple of the step direction added to the previous iterate. 2494 2495 Options Database Key: 2496 . -tao_monitor - Use the default monitor, which prints statistics to standard output 2497 2498 Level: developer 2499 2500 .seealso: [](ch_tao), `Tao`, `TaoGetConvergedReason()`, `TaoMonitorDefault()`, `TaoMonitorSet()` 2501 @*/ 2502 PetscErrorCode TaoMonitor(Tao tao, PetscInt its, PetscReal f, PetscReal res, PetscReal cnorm, PetscReal steplength) 2503 { 2504 PetscInt i; 2505 2506 PetscFunctionBegin; 2507 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 2508 tao->fc = f; 2509 tao->residual = res; 2510 tao->cnorm = cnorm; 2511 tao->step = steplength; 2512 if (!its) { 2513 tao->cnorm0 = cnorm; 2514 tao->gnorm0 = res; 2515 } 2516 PetscCall(VecLockReadPush(tao->solution)); 2517 for (i = 0; i < tao->numbermonitors; i++) PetscCall((*tao->monitor[i])(tao, tao->monitorcontext[i])); 2518 PetscCall(VecLockReadPop(tao->solution)); 2519 PetscFunctionReturn(PETSC_SUCCESS); 2520 } 2521 2522 /*@ 2523 TaoSetConvergenceHistory - Sets the array used to hold the convergence history. 2524 2525 Logically Collective 2526 2527 Input Parameters: 2528 + tao - the `Tao` solver context 2529 . obj - array to hold objective value history 2530 . resid - array to hold residual history 2531 . cnorm - array to hold constraint violation history 2532 . lits - integer array holds the number of linear iterations for each Tao iteration 2533 . na - size of `obj`, `resid`, and `cnorm` 2534 - reset - `PETSC_TRUE` indicates each new minimization resets the history counter to zero, 2535 else it continues storing new values for new minimizations after the old ones 2536 2537 Level: intermediate 2538 2539 Notes: 2540 If set, `Tao` will fill the given arrays with the indicated 2541 information at each iteration. If 'obj','resid','cnorm','lits' are 2542 *all* `NULL` then space (using size `na`, or 1000 if `na` is `PETSC_DECIDE`) is allocated for the history. 2543 If not all are `NULL`, then only the non-`NULL` information categories 2544 will be stored, the others will be ignored. 2545 2546 Any convergence information after iteration number 'na' will not be stored. 2547 2548 This routine is useful, e.g., when running a code for purposes 2549 of accurate performance monitoring, when no I/O should be done 2550 during the section of code that is being timed. 2551 2552 .seealso: [](ch_tao), `TaoGetConvergenceHistory()` 2553 @*/ 2554 PetscErrorCode TaoSetConvergenceHistory(Tao tao, PetscReal obj[], PetscReal resid[], PetscReal cnorm[], PetscInt lits[], PetscInt na, PetscBool reset) 2555 { 2556 PetscFunctionBegin; 2557 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 2558 if (obj) PetscAssertPointer(obj, 2); 2559 if (resid) PetscAssertPointer(resid, 3); 2560 if (cnorm) PetscAssertPointer(cnorm, 4); 2561 if (lits) PetscAssertPointer(lits, 5); 2562 2563 if (na == PETSC_DECIDE || na == PETSC_CURRENT) na = 1000; 2564 if (!obj && !resid && !cnorm && !lits) { 2565 PetscCall(PetscCalloc4(na, &obj, na, &resid, na, &cnorm, na, &lits)); 2566 tao->hist_malloc = PETSC_TRUE; 2567 } 2568 2569 tao->hist_obj = obj; 2570 tao->hist_resid = resid; 2571 tao->hist_cnorm = cnorm; 2572 tao->hist_lits = lits; 2573 tao->hist_max = na; 2574 tao->hist_reset = reset; 2575 tao->hist_len = 0; 2576 PetscFunctionReturn(PETSC_SUCCESS); 2577 } 2578 2579 /*@C 2580 TaoGetConvergenceHistory - Gets the arrays used that hold the convergence history. 2581 2582 Collective 2583 2584 Input Parameter: 2585 . tao - the `Tao` context 2586 2587 Output Parameters: 2588 + obj - array used to hold objective value history 2589 . resid - array used to hold residual history 2590 . cnorm - array used to hold constraint violation history 2591 . lits - integer array used to hold linear solver iteration count 2592 - nhist - size of `obj`, `resid`, `cnorm`, and `lits` 2593 2594 Level: advanced 2595 2596 Notes: 2597 This routine must be preceded by calls to `TaoSetConvergenceHistory()` 2598 and `TaoSolve()`, otherwise it returns useless information. 2599 2600 This routine is useful, e.g., when running a code for purposes 2601 of accurate performance monitoring, when no I/O should be done 2602 during the section of code that is being timed. 2603 2604 Fortran Notes: 2605 The calling sequence is 2606 .vb 2607 call TaoGetConvergenceHistory(Tao tao, PetscInt nhist, PetscErrorCode ierr) 2608 .ve 2609 In other words this gets the current number of entries in the history. Access the history through the array you passed to `TaoSetConvergenceHistory()` 2610 2611 .seealso: [](ch_tao), `Tao`, `TaoSolve()`, `TaoSetConvergenceHistory()` 2612 @*/ 2613 PetscErrorCode TaoGetConvergenceHistory(Tao tao, PetscReal **obj, PetscReal **resid, PetscReal **cnorm, PetscInt **lits, PetscInt *nhist) 2614 { 2615 PetscFunctionBegin; 2616 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 2617 if (obj) *obj = tao->hist_obj; 2618 if (cnorm) *cnorm = tao->hist_cnorm; 2619 if (resid) *resid = tao->hist_resid; 2620 if (lits) *lits = tao->hist_lits; 2621 if (nhist) *nhist = tao->hist_len; 2622 PetscFunctionReturn(PETSC_SUCCESS); 2623 } 2624 2625 /*@ 2626 TaoSetApplicationContext - Sets the optional user-defined context for a `Tao` solver that can be accessed later, for example in the 2627 `Tao` callback functions with `TaoGetApplicationContext()` 2628 2629 Logically Collective 2630 2631 Input Parameters: 2632 + tao - the `Tao` context 2633 - ctx - the user context 2634 2635 Level: intermediate 2636 2637 Fortran Note: 2638 This only works when `ctx` is a Fortran derived type (it cannot be a `PetscObject`), we recommend writing a Fortran interface definition for this 2639 function that tells the Fortran compiler the derived data type that is passed in as the `ctx` argument. See `TaoGetApplicationContext()` for 2640 an example. 2641 2642 .seealso: [](ch_tao), `Tao`, `TaoGetApplicationContext()` 2643 @*/ 2644 PetscErrorCode TaoSetApplicationContext(Tao tao, void *ctx) 2645 { 2646 PetscFunctionBegin; 2647 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 2648 tao->ctx = ctx; 2649 PetscFunctionReturn(PETSC_SUCCESS); 2650 } 2651 2652 /*@ 2653 TaoGetApplicationContext - Gets the user-defined context for a `Tao` solver provided with `TaoSetApplicationContext()` 2654 2655 Not Collective 2656 2657 Input Parameter: 2658 . tao - the `Tao` context 2659 2660 Output Parameter: 2661 . ctx - a pointer to the user context 2662 2663 Level: intermediate 2664 2665 Fortran Notes: 2666 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 2667 function that tells the Fortran compiler the derived data type that is returned as the `ctx` argument. For example, 2668 .vb 2669 Interface TaoGetApplicationContext 2670 Subroutine TaoGetApplicationContext(tao,ctx,ierr) 2671 #include <petsc/finclude/petsctao.h> 2672 use petsctao 2673 Tao tao 2674 type(tUsertype), pointer :: ctx 2675 PetscErrorCode ierr 2676 End Subroutine 2677 End Interface TaoGetApplicationContext 2678 .ve 2679 2680 The prototype for `ctx` must be 2681 .vb 2682 type(tUsertype), pointer :: ctx 2683 .ve 2684 2685 .seealso: [](ch_tao), `Tao`, `TaoSetApplicationContext()` 2686 @*/ 2687 PetscErrorCode TaoGetApplicationContext(Tao tao, PeCtx ctx) 2688 { 2689 PetscFunctionBegin; 2690 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 2691 PetscAssertPointer(ctx, 2); 2692 *(void **)ctx = tao->ctx; 2693 PetscFunctionReturn(PETSC_SUCCESS); 2694 } 2695 2696 /*@ 2697 TaoSetGradientNorm - Sets the matrix used to define the norm that measures the size of the gradient in some of the `Tao` algorithms 2698 2699 Collective 2700 2701 Input Parameters: 2702 + tao - the `Tao` context 2703 - M - matrix that defines the norm 2704 2705 Level: beginner 2706 2707 .seealso: [](ch_tao), `Tao`, `TaoGetGradientNorm()`, `TaoGradientNorm()` 2708 @*/ 2709 PetscErrorCode TaoSetGradientNorm(Tao tao, Mat M) 2710 { 2711 PetscFunctionBegin; 2712 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 2713 PetscValidHeaderSpecific(M, MAT_CLASSID, 2); 2714 PetscCall(PetscObjectReference((PetscObject)M)); 2715 PetscCall(MatDestroy(&tao->gradient_norm)); 2716 PetscCall(VecDestroy(&tao->gradient_norm_tmp)); 2717 tao->gradient_norm = M; 2718 PetscCall(MatCreateVecs(M, NULL, &tao->gradient_norm_tmp)); 2719 PetscFunctionReturn(PETSC_SUCCESS); 2720 } 2721 2722 /*@ 2723 TaoGetGradientNorm - Returns the matrix used to define the norm used for measuring the size of the gradient in some of the `Tao` algorithms 2724 2725 Not Collective 2726 2727 Input Parameter: 2728 . tao - the `Tao` context 2729 2730 Output Parameter: 2731 . M - gradient norm 2732 2733 Level: beginner 2734 2735 .seealso: [](ch_tao), `Tao`, `TaoSetGradientNorm()`, `TaoGradientNorm()` 2736 @*/ 2737 PetscErrorCode TaoGetGradientNorm(Tao tao, Mat *M) 2738 { 2739 PetscFunctionBegin; 2740 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 2741 PetscAssertPointer(M, 2); 2742 *M = tao->gradient_norm; 2743 PetscFunctionReturn(PETSC_SUCCESS); 2744 } 2745 2746 /*@ 2747 TaoGradientNorm - Compute the norm using the `NormType`, the user has selected 2748 2749 Collective 2750 2751 Input Parameters: 2752 + tao - the `Tao` context 2753 . gradient - the gradient 2754 - type - the norm type 2755 2756 Output Parameter: 2757 . gnorm - the gradient norm 2758 2759 Level: advanced 2760 2761 Note: 2762 If `TaoSetGradientNorm()` has been set and `type` is `NORM_2` then the norm provided with `TaoSetGradientNorm()` is used. 2763 2764 Developer Notes: 2765 Should be named `TaoComputeGradientNorm()`. 2766 2767 The usage is a bit confusing, with `TaoSetGradientNorm()` plus `NORM_2` resulting in the computation of the user provided 2768 norm, perhaps a refactorization is in order. 2769 2770 .seealso: [](ch_tao), `Tao`, `TaoSetGradientNorm()`, `TaoGetGradientNorm()` 2771 @*/ 2772 PetscErrorCode TaoGradientNorm(Tao tao, Vec gradient, NormType type, PetscReal *gnorm) 2773 { 2774 PetscFunctionBegin; 2775 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 2776 PetscValidHeaderSpecific(gradient, VEC_CLASSID, 2); 2777 PetscValidLogicalCollectiveEnum(tao, type, 3); 2778 PetscAssertPointer(gnorm, 4); 2779 if (tao->gradient_norm) { 2780 PetscScalar gnorms; 2781 2782 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."); 2783 PetscCall(MatMult(tao->gradient_norm, gradient, tao->gradient_norm_tmp)); 2784 PetscCall(VecDot(gradient, tao->gradient_norm_tmp, &gnorms)); 2785 *gnorm = PetscRealPart(PetscSqrtScalar(gnorms)); 2786 } else { 2787 PetscCall(VecNorm(gradient, type, gnorm)); 2788 } 2789 PetscFunctionReturn(PETSC_SUCCESS); 2790 } 2791 2792 /*@C 2793 TaoMonitorDrawCtxCreate - Creates the monitor context for `TaoMonitorSolutionDraw()` 2794 2795 Collective 2796 2797 Input Parameters: 2798 + comm - the communicator to share the context 2799 . host - the name of the X Windows host that will display the monitor 2800 . label - the label to put at the top of the display window 2801 . x - the horizontal coordinate of the lower left corner of the window to open 2802 . y - the vertical coordinate of the lower left corner of the window to open 2803 . m - the width of the window 2804 . n - the height of the window 2805 - howoften - how many `Tao` iterations between displaying the monitor information 2806 2807 Output Parameter: 2808 . ctx - the monitor context 2809 2810 Options Database Keys: 2811 + -tao_monitor_solution_draw - use `TaoMonitorSolutionDraw()` to monitor the solution 2812 - -tao_draw_solution_initial - show initial guess as well as current solution 2813 2814 Level: intermediate 2815 2816 Note: 2817 The context this creates, along with `TaoMonitorSolutionDraw()`, and `TaoMonitorDrawCtxDestroy()` 2818 are passed to `TaoMonitorSet()`. 2819 2820 .seealso: [](ch_tao), `Tao`, `TaoMonitorSet()`, `TaoMonitorDefault()`, `VecView()`, `TaoMonitorDrawCtx()` 2821 @*/ 2822 PetscErrorCode TaoMonitorDrawCtxCreate(MPI_Comm comm, const char host[], const char label[], int x, int y, int m, int n, PetscInt howoften, TaoMonitorDrawCtx *ctx) 2823 { 2824 PetscFunctionBegin; 2825 PetscCall(PetscNew(ctx)); 2826 PetscCall(PetscViewerDrawOpen(comm, host, label, x, y, m, n, &(*ctx)->viewer)); 2827 PetscCall(PetscViewerSetFromOptions((*ctx)->viewer)); 2828 (*ctx)->howoften = howoften; 2829 PetscFunctionReturn(PETSC_SUCCESS); 2830 } 2831 2832 /*@C 2833 TaoMonitorDrawCtxDestroy - Destroys the monitor context for `TaoMonitorSolutionDraw()` 2834 2835 Collective 2836 2837 Input Parameter: 2838 . ictx - the monitor context 2839 2840 Level: intermediate 2841 2842 Note: 2843 This is passed to `TaoMonitorSet()` as the final argument, along with `TaoMonitorSolutionDraw()`, and the context 2844 obtained with `TaoMonitorDrawCtxCreate()`. 2845 2846 .seealso: [](ch_tao), `Tao`, `TaoMonitorSet()`, `TaoMonitorDefault()`, `VecView()`, `TaoMonitorSolutionDraw()` 2847 @*/ 2848 PetscErrorCode TaoMonitorDrawCtxDestroy(TaoMonitorDrawCtx *ictx) 2849 { 2850 PetscFunctionBegin; 2851 PetscCall(PetscViewerDestroy(&(*ictx)->viewer)); 2852 PetscCall(PetscFree(*ictx)); 2853 PetscFunctionReturn(PETSC_SUCCESS); 2854 } 2855