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