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