1 2 #include <petsc/private/tsimpl.h> /*I "petscts.h" I*/ 3 4 PetscClassId TSADAPT_CLASSID; 5 6 static PetscFunctionList TSAdaptList; 7 static PetscBool TSAdaptPackageInitialized; 8 static PetscBool TSAdaptRegisterAllCalled; 9 10 PETSC_EXTERN PetscErrorCode TSAdaptCreate_None(TSAdapt); 11 PETSC_EXTERN PetscErrorCode TSAdaptCreate_Basic(TSAdapt); 12 PETSC_EXTERN PetscErrorCode TSAdaptCreate_DSP(TSAdapt); 13 PETSC_EXTERN PetscErrorCode TSAdaptCreate_CFL(TSAdapt); 14 PETSC_EXTERN PetscErrorCode TSAdaptCreate_GLEE(TSAdapt); 15 PETSC_EXTERN PetscErrorCode TSAdaptCreate_History(TSAdapt); 16 17 /*@C 18 TSAdaptRegister - adds a TSAdapt implementation 19 20 Not Collective 21 22 Input Parameters: 23 + name_scheme - name of user-defined adaptivity scheme 24 - routine_create - routine to create method context 25 26 Notes: 27 TSAdaptRegister() may be called multiple times to add several user-defined families. 28 29 Sample usage: 30 .vb 31 TSAdaptRegister("my_scheme",MySchemeCreate); 32 .ve 33 34 Then, your scheme can be chosen with the procedural interface via 35 $ TSAdaptSetType(ts,"my_scheme") 36 or at runtime via the option 37 $ -ts_adapt_type my_scheme 38 39 Level: advanced 40 41 .seealso: TSAdaptRegisterAll() 42 @*/ 43 PetscErrorCode TSAdaptRegister(const char sname[],PetscErrorCode (*function)(TSAdapt)) 44 { 45 PetscErrorCode ierr; 46 47 PetscFunctionBegin; 48 ierr = TSAdaptInitializePackage();CHKERRQ(ierr); 49 ierr = PetscFunctionListAdd(&TSAdaptList,sname,function);CHKERRQ(ierr); 50 PetscFunctionReturn(0); 51 } 52 53 /*@C 54 TSAdaptRegisterAll - Registers all of the adaptivity schemes in TSAdapt 55 56 Not Collective 57 58 Level: advanced 59 60 .seealso: TSAdaptRegisterDestroy() 61 @*/ 62 PetscErrorCode TSAdaptRegisterAll(void) 63 { 64 PetscErrorCode ierr; 65 66 PetscFunctionBegin; 67 if (TSAdaptRegisterAllCalled) PetscFunctionReturn(0); 68 TSAdaptRegisterAllCalled = PETSC_TRUE; 69 ierr = TSAdaptRegister(TSADAPTNONE, TSAdaptCreate_None);CHKERRQ(ierr); 70 ierr = TSAdaptRegister(TSADAPTBASIC, TSAdaptCreate_Basic);CHKERRQ(ierr); 71 ierr = TSAdaptRegister(TSADAPTDSP, TSAdaptCreate_DSP);CHKERRQ(ierr); 72 ierr = TSAdaptRegister(TSADAPTCFL, TSAdaptCreate_CFL);CHKERRQ(ierr); 73 ierr = TSAdaptRegister(TSADAPTGLEE, TSAdaptCreate_GLEE);CHKERRQ(ierr); 74 ierr = TSAdaptRegister(TSADAPTHISTORY,TSAdaptCreate_History);CHKERRQ(ierr); 75 PetscFunctionReturn(0); 76 } 77 78 /*@C 79 TSAdaptFinalizePackage - This function destroys everything in the TS package. It is 80 called from PetscFinalize(). 81 82 Level: developer 83 84 .seealso: PetscFinalize() 85 @*/ 86 PetscErrorCode TSAdaptFinalizePackage(void) 87 { 88 PetscErrorCode ierr; 89 90 PetscFunctionBegin; 91 ierr = PetscFunctionListDestroy(&TSAdaptList);CHKERRQ(ierr); 92 TSAdaptPackageInitialized = PETSC_FALSE; 93 TSAdaptRegisterAllCalled = PETSC_FALSE; 94 PetscFunctionReturn(0); 95 } 96 97 /*@C 98 TSAdaptInitializePackage - This function initializes everything in the TSAdapt package. It is 99 called from TSInitializePackage(). 100 101 Level: developer 102 103 .seealso: PetscInitialize() 104 @*/ 105 PetscErrorCode TSAdaptInitializePackage(void) 106 { 107 PetscErrorCode ierr; 108 109 PetscFunctionBegin; 110 if (TSAdaptPackageInitialized) PetscFunctionReturn(0); 111 TSAdaptPackageInitialized = PETSC_TRUE; 112 ierr = PetscClassIdRegister("TSAdapt",&TSADAPT_CLASSID);CHKERRQ(ierr); 113 ierr = TSAdaptRegisterAll();CHKERRQ(ierr); 114 ierr = PetscRegisterFinalize(TSAdaptFinalizePackage);CHKERRQ(ierr); 115 PetscFunctionReturn(0); 116 } 117 118 /*@C 119 TSAdaptSetType - sets the approach used for the error adapter, currently there is only TSADAPTBASIC and TSADAPTNONE 120 121 Logicially Collective on TSAdapt 122 123 Input Parameter: 124 + adapt - the TS adapter, most likely obtained with TSGetAdapt() 125 - type - either TSADAPTBASIC or TSADAPTNONE 126 127 Options Database: 128 . -ts_adapt_type <basic or dsp or none> - to set the adapter type 129 130 Level: intermediate 131 132 .seealso: TSGetAdapt(), TSAdaptDestroy(), TSAdaptType, TSAdaptGetType() 133 @*/ 134 PetscErrorCode TSAdaptSetType(TSAdapt adapt,TSAdaptType type) 135 { 136 PetscBool match; 137 PetscErrorCode ierr,(*r)(TSAdapt); 138 139 PetscFunctionBegin; 140 PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1); 141 PetscValidCharPointer(type,2); 142 ierr = PetscObjectTypeCompare((PetscObject)adapt,type,&match);CHKERRQ(ierr); 143 if (match) PetscFunctionReturn(0); 144 ierr = PetscFunctionListFind(TSAdaptList,type,&r);CHKERRQ(ierr); 145 if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown TSAdapt type \"%s\" given",type); 146 if (adapt->ops->destroy) {ierr = (*adapt->ops->destroy)(adapt);CHKERRQ(ierr);} 147 ierr = PetscMemzero(adapt->ops,sizeof(struct _TSAdaptOps));CHKERRQ(ierr); 148 ierr = PetscObjectChangeTypeName((PetscObject)adapt,type);CHKERRQ(ierr); 149 ierr = (*r)(adapt);CHKERRQ(ierr); 150 PetscFunctionReturn(0); 151 } 152 153 /*@C 154 TSAdaptGetType - gets the TS adapter method type (as a string). 155 156 Not Collective 157 158 Input Parameter: 159 . adapt - The TS adapter, most likely obtained with TSGetAdapt() 160 161 Output Parameter: 162 . type - The name of TS adapter method 163 164 Level: intermediate 165 166 .seealso TSAdaptSetType() 167 @*/ 168 PetscErrorCode TSAdaptGetType(TSAdapt adapt,TSAdaptType *type) 169 { 170 PetscFunctionBegin; 171 PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1); 172 PetscValidPointer(type,2); 173 *type = ((PetscObject)adapt)->type_name; 174 PetscFunctionReturn(0); 175 } 176 177 PetscErrorCode TSAdaptSetOptionsPrefix(TSAdapt adapt,const char prefix[]) 178 { 179 PetscErrorCode ierr; 180 181 PetscFunctionBegin; 182 PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1); 183 ierr = PetscObjectSetOptionsPrefix((PetscObject)adapt,prefix);CHKERRQ(ierr); 184 PetscFunctionReturn(0); 185 } 186 187 /*@C 188 TSAdaptLoad - Loads a TSAdapt that has been stored in binary with TSAdaptView(). 189 190 Collective on PetscViewer 191 192 Input Parameters: 193 + newdm - the newly loaded TSAdapt, this needs to have been created with TSAdaptCreate() or 194 some related function before a call to TSAdaptLoad(). 195 - viewer - binary file viewer, obtained from PetscViewerBinaryOpen() or 196 HDF5 file viewer, obtained from PetscViewerHDF5Open() 197 198 Level: intermediate 199 200 Notes: 201 The type is determined by the data in the file, any type set into the TSAdapt before this call is ignored. 202 203 Notes for advanced users: 204 Most users should not need to know the details of the binary storage 205 format, since TSAdaptLoad() and TSAdaptView() completely hide these details. 206 But for anyone who's interested, the standard binary matrix storage 207 format is 208 .vb 209 has not yet been determined 210 .ve 211 212 .seealso: PetscViewerBinaryOpen(), TSAdaptView(), MatLoad(), VecLoad() 213 @*/ 214 PetscErrorCode TSAdaptLoad(TSAdapt adapt,PetscViewer viewer) 215 { 216 PetscErrorCode ierr; 217 PetscBool isbinary; 218 char type[256]; 219 220 PetscFunctionBegin; 221 PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1); 222 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 223 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 224 if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()"); 225 226 ierr = PetscViewerBinaryRead(viewer,type,256,NULL,PETSC_CHAR);CHKERRQ(ierr); 227 ierr = TSAdaptSetType(adapt,type);CHKERRQ(ierr); 228 if (adapt->ops->load) { 229 ierr = (*adapt->ops->load)(adapt,viewer);CHKERRQ(ierr); 230 } 231 PetscFunctionReturn(0); 232 } 233 234 PetscErrorCode TSAdaptView(TSAdapt adapt,PetscViewer viewer) 235 { 236 PetscErrorCode ierr; 237 PetscBool iascii,isbinary,isnone,isglee; 238 239 PetscFunctionBegin; 240 PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1); 241 if (!viewer) {ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)adapt),&viewer);CHKERRQ(ierr);} 242 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 243 PetscCheckSameComm(adapt,1,viewer,2); 244 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 245 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 246 if (iascii) { 247 ierr = PetscObjectPrintClassNamePrefixType((PetscObject)adapt,viewer);CHKERRQ(ierr); 248 ierr = PetscObjectTypeCompare((PetscObject)adapt,TSADAPTNONE,&isnone);CHKERRQ(ierr); 249 ierr = PetscObjectTypeCompare((PetscObject)adapt,TSADAPTGLEE,&isglee);CHKERRQ(ierr); 250 if (!isnone) { 251 if (adapt->always_accept) {ierr = PetscViewerASCIIPrintf(viewer," always accepting steps\n");CHKERRQ(ierr);} 252 ierr = PetscViewerASCIIPrintf(viewer," safety factor %g\n",(double)adapt->safety);CHKERRQ(ierr); 253 ierr = PetscViewerASCIIPrintf(viewer," extra safety factor after step rejection %g\n",(double)adapt->reject_safety);CHKERRQ(ierr); 254 ierr = PetscViewerASCIIPrintf(viewer," clip fastest increase %g\n",(double)adapt->clip[1]);CHKERRQ(ierr); 255 ierr = PetscViewerASCIIPrintf(viewer," clip fastest decrease %g\n",(double)adapt->clip[0]);CHKERRQ(ierr); 256 ierr = PetscViewerASCIIPrintf(viewer," maximum allowed timestep %g\n",(double)adapt->dt_max);CHKERRQ(ierr); 257 ierr = PetscViewerASCIIPrintf(viewer," minimum allowed timestep %g\n",(double)adapt->dt_min);CHKERRQ(ierr); 258 ierr = PetscViewerASCIIPrintf(viewer," maximum solution absolute value to be ignored %g\n",(double)adapt->ignore_max);CHKERRQ(ierr); 259 } 260 if (isglee) { 261 if (adapt->glee_use_local) { 262 ierr = PetscViewerASCIIPrintf(viewer," GLEE uses local error control\n");CHKERRQ(ierr); 263 } else { 264 ierr = PetscViewerASCIIPrintf(viewer," GLEE uses global error control\n");CHKERRQ(ierr); 265 } 266 } 267 if (adapt->ops->view) { 268 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 269 ierr = (*adapt->ops->view)(adapt,viewer);CHKERRQ(ierr); 270 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 271 } 272 } else if (isbinary) { 273 char type[256]; 274 275 /* need to save FILE_CLASS_ID for adapt class */ 276 ierr = PetscStrncpy(type,((PetscObject)adapt)->type_name,256);CHKERRQ(ierr); 277 ierr = PetscViewerBinaryWrite(viewer,type,256,PETSC_CHAR);CHKERRQ(ierr); 278 } else if (adapt->ops->view) { 279 ierr = (*adapt->ops->view)(adapt,viewer);CHKERRQ(ierr); 280 } 281 PetscFunctionReturn(0); 282 } 283 284 /*@ 285 TSAdaptReset - Resets a TSAdapt context. 286 287 Collective on TS 288 289 Input Parameter: 290 . adapt - the TSAdapt context obtained from TSAdaptCreate() 291 292 Level: developer 293 294 .seealso: TSAdaptCreate(), TSAdaptDestroy() 295 @*/ 296 PetscErrorCode TSAdaptReset(TSAdapt adapt) 297 { 298 PetscErrorCode ierr; 299 300 PetscFunctionBegin; 301 PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1); 302 if (adapt->ops->reset) {ierr = (*adapt->ops->reset)(adapt);CHKERRQ(ierr);} 303 PetscFunctionReturn(0); 304 } 305 306 PetscErrorCode TSAdaptDestroy(TSAdapt *adapt) 307 { 308 PetscErrorCode ierr; 309 310 PetscFunctionBegin; 311 if (!*adapt) PetscFunctionReturn(0); 312 PetscValidHeaderSpecific(*adapt,TSADAPT_CLASSID,1); 313 if (--((PetscObject)(*adapt))->refct > 0) {*adapt = NULL; PetscFunctionReturn(0);} 314 315 ierr = TSAdaptReset(*adapt);CHKERRQ(ierr); 316 317 if ((*adapt)->ops->destroy) {ierr = (*(*adapt)->ops->destroy)(*adapt);CHKERRQ(ierr);} 318 ierr = PetscViewerDestroy(&(*adapt)->monitor);CHKERRQ(ierr); 319 ierr = PetscHeaderDestroy(adapt);CHKERRQ(ierr); 320 PetscFunctionReturn(0); 321 } 322 323 /*@ 324 TSAdaptSetMonitor - Monitor the choices made by the adaptive controller 325 326 Collective on TSAdapt 327 328 Input Arguments: 329 + adapt - adaptive controller context 330 - flg - PETSC_TRUE to active a monitor, PETSC_FALSE to disable 331 332 Options Database Keys: 333 . -ts_adapt_monitor - to turn on monitoring 334 335 Level: intermediate 336 337 .seealso: TSAdaptChoose() 338 @*/ 339 PetscErrorCode TSAdaptSetMonitor(TSAdapt adapt,PetscBool flg) 340 { 341 PetscErrorCode ierr; 342 343 PetscFunctionBegin; 344 PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1); 345 PetscValidLogicalCollectiveBool(adapt,flg,2); 346 if (flg) { 347 if (!adapt->monitor) {ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)adapt),"stdout",&adapt->monitor);CHKERRQ(ierr);} 348 } else { 349 ierr = PetscViewerDestroy(&adapt->monitor);CHKERRQ(ierr); 350 } 351 PetscFunctionReturn(0); 352 } 353 354 /*@C 355 TSAdaptSetCheckStage - Set a callback to check convergence for a stage 356 357 Logically collective on TSAdapt 358 359 Input Arguments: 360 + adapt - adaptive controller context 361 - func - stage check function 362 363 Arguments of func: 364 $ PetscErrorCode func(TSAdapt adapt,TS ts,PetscBool *accept) 365 366 + adapt - adaptive controller context 367 . ts - time stepping context 368 - accept - pending choice of whether to accept, can be modified by this routine 369 370 Level: advanced 371 372 .seealso: TSAdaptChoose() 373 @*/ 374 PetscErrorCode TSAdaptSetCheckStage(TSAdapt adapt,PetscErrorCode (*func)(TSAdapt,TS,PetscReal,Vec,PetscBool*)) 375 { 376 PetscFunctionBegin; 377 PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1); 378 adapt->checkstage = func; 379 PetscFunctionReturn(0); 380 } 381 382 /*@ 383 TSAdaptSetAlwaysAccept - Set whether to always accept steps regardless of 384 any error or stability condition not meeting the prescribed goal. 385 386 Logically collective on TSAdapt 387 388 Input Arguments: 389 + adapt - time step adaptivity context, usually gotten with TSGetAdapt() 390 - flag - whether to always accept steps 391 392 Options Database Keys: 393 . -ts_adapt_always_accept - to always accept steps 394 395 Level: intermediate 396 397 .seealso: TSAdapt, TSAdaptChoose() 398 @*/ 399 PetscErrorCode TSAdaptSetAlwaysAccept(TSAdapt adapt,PetscBool flag) 400 { 401 PetscFunctionBegin; 402 PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1); 403 PetscValidLogicalCollectiveBool(adapt,flag,2); 404 adapt->always_accept = flag; 405 PetscFunctionReturn(0); 406 } 407 408 /*@ 409 TSAdaptSetSafety - Set safety factors 410 411 Logically collective on TSAdapt 412 413 Input Arguments: 414 + adapt - adaptive controller context 415 . safety - safety factor relative to target error/stability goal 416 - reject_safety - extra safety factor to apply if the last step was rejected 417 418 Options Database Keys: 419 + -ts_adapt_safety <safety> - to set safety factor 420 - -ts_adapt_reject_safety <reject_safety> - to set reject safety factor 421 422 Level: intermediate 423 424 .seealso: TSAdapt, TSAdaptGetSafety(), TSAdaptChoose() 425 @*/ 426 PetscErrorCode TSAdaptSetSafety(TSAdapt adapt,PetscReal safety,PetscReal reject_safety) 427 { 428 PetscFunctionBegin; 429 PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1); 430 PetscValidLogicalCollectiveReal(adapt,safety,2); 431 PetscValidLogicalCollectiveReal(adapt,reject_safety,3); 432 if (safety != PETSC_DEFAULT && safety < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Safety factor %g must be non negative",(double)safety); 433 if (safety != PETSC_DEFAULT && safety > 1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Safety factor %g must be less than one",(double)safety); 434 if (reject_safety != PETSC_DEFAULT && reject_safety < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Reject safety factor %g must be non negative",(double)reject_safety); 435 if (reject_safety != PETSC_DEFAULT && reject_safety > 1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Reject safety factor %g must be less than one",(double)reject_safety); 436 if (safety != PETSC_DEFAULT) adapt->safety = safety; 437 if (reject_safety != PETSC_DEFAULT) adapt->reject_safety = reject_safety; 438 PetscFunctionReturn(0); 439 } 440 441 /*@ 442 TSAdaptGetSafety - Get safety factors 443 444 Not Collective 445 446 Input Arguments: 447 . adapt - adaptive controller context 448 449 Ouput Arguments: 450 . safety - safety factor relative to target error/stability goal 451 + reject_safety - extra safety factor to apply if the last step was rejected 452 453 Level: intermediate 454 455 .seealso: TSAdapt, TSAdaptSetSafety(), TSAdaptChoose() 456 @*/ 457 PetscErrorCode TSAdaptGetSafety(TSAdapt adapt,PetscReal *safety,PetscReal *reject_safety) 458 { 459 PetscFunctionBegin; 460 PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1); 461 if (safety) PetscValidRealPointer(safety,2); 462 if (reject_safety) PetscValidRealPointer(reject_safety,3); 463 if (safety) *safety = adapt->safety; 464 if (reject_safety) *reject_safety = adapt->reject_safety; 465 PetscFunctionReturn(0); 466 } 467 468 /*@ 469 TSAdaptSetMaxIgnore - Set error estimation threshold. Solution components below this threshold value will not be considered when computing error norms for time step adaptivity (in absolute value). A negative value (default) of the threshold leads to considering all solution components. 470 471 Logically collective on TSAdapt 472 473 Input Arguments: 474 + adapt - adaptive controller context 475 - max_ignore - threshold for solution components that are ignored during error estimation 476 477 Options Database Keys: 478 . -ts_adapt_max_ignore <max_ignore> - to set the threshold 479 480 Level: intermediate 481 482 .seealso: TSAdapt, TSAdaptGetMaxIgnore(), TSAdaptChoose() 483 @*/ 484 PetscErrorCode TSAdaptSetMaxIgnore(TSAdapt adapt,PetscReal max_ignore) 485 { 486 PetscFunctionBegin; 487 PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1); 488 PetscValidLogicalCollectiveReal(adapt,max_ignore,2); 489 adapt->ignore_max = max_ignore; 490 PetscFunctionReturn(0); 491 } 492 493 /*@ 494 TSAdaptGetMaxIgnore - Get error estimation threshold. Solution components below this threshold value will not be considered when computing error norms for time step adaptivity (in absolute value). 495 496 Not Collective 497 498 Input Arguments: 499 . adapt - adaptive controller context 500 501 Ouput Arguments: 502 . max_ignore - threshold for solution components that are ignored during error estimation 503 504 Level: intermediate 505 506 .seealso: TSAdapt, TSAdaptSetMaxIgnore(), TSAdaptChoose() 507 @*/ 508 PetscErrorCode TSAdaptGetMaxIgnore(TSAdapt adapt,PetscReal *max_ignore) 509 { 510 PetscFunctionBegin; 511 PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1); 512 PetscValidRealPointer(max_ignore,2); 513 *max_ignore = adapt->ignore_max; 514 PetscFunctionReturn(0); 515 } 516 517 /*@ 518 TSAdaptSetClip - Sets the admissible decrease/increase factor in step size 519 520 Logically collective on TSAdapt 521 522 Input Arguments: 523 + adapt - adaptive controller context 524 . low - admissible decrease factor 525 - high - admissible increase factor 526 527 Options Database Keys: 528 . -ts_adapt_clip <low>,<high> - to set admissible time step decrease and increase factors 529 530 Level: intermediate 531 532 .seealso: TSAdaptChoose(), TSAdaptGetClip(), TSAdaptSetScaleSolveFailed() 533 @*/ 534 PetscErrorCode TSAdaptSetClip(TSAdapt adapt,PetscReal low,PetscReal high) 535 { 536 PetscFunctionBegin; 537 PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1); 538 PetscValidLogicalCollectiveReal(adapt,low,2); 539 PetscValidLogicalCollectiveReal(adapt,high,3); 540 if (low != PETSC_DEFAULT && low < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Decrease factor %g must be non negative",(double)low); 541 if (low != PETSC_DEFAULT && low > 1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Decrease factor %g must be less than one",(double)low); 542 if (high != PETSC_DEFAULT && high < 1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Increase factor %g must be greater than one",(double)high); 543 if (low != PETSC_DEFAULT) adapt->clip[0] = low; 544 if (high != PETSC_DEFAULT) adapt->clip[1] = high; 545 PetscFunctionReturn(0); 546 } 547 548 /*@ 549 TSAdaptGetClip - Gets the admissible decrease/increase factor in step size 550 551 Not Collective 552 553 Input Arguments: 554 . adapt - adaptive controller context 555 556 Ouput Arguments: 557 + low - optional, admissible decrease factor 558 - high - optional, admissible increase factor 559 560 Level: intermediate 561 562 .seealso: TSAdaptChoose(), TSAdaptSetClip(), TSAdaptSetScaleSolveFailed() 563 @*/ 564 PetscErrorCode TSAdaptGetClip(TSAdapt adapt,PetscReal *low,PetscReal *high) 565 { 566 PetscFunctionBegin; 567 PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1); 568 if (low) PetscValidRealPointer(low,2); 569 if (high) PetscValidRealPointer(high,3); 570 if (low) *low = adapt->clip[0]; 571 if (high) *high = adapt->clip[1]; 572 PetscFunctionReturn(0); 573 } 574 575 /*@ 576 TSAdaptSetScaleSolveFailed - Scale step by this factor if solve fails 577 578 Logically collective on TSAdapt 579 580 Input Arguments: 581 + adapt - adaptive controller context 582 - scale - scale 583 584 Options Database Keys: 585 . -ts_adapt_scale_solve_failed <scale> - to set scale step by this factor if solve fails 586 587 Level: intermediate 588 589 .seealso: TSAdaptChoose(), TSAdaptGetScaleSolveFailed(), TSAdaptGetClip() 590 @*/ 591 PetscErrorCode TSAdaptSetScaleSolveFailed(TSAdapt adapt,PetscReal scale) 592 { 593 PetscFunctionBegin; 594 PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1); 595 PetscValidLogicalCollectiveReal(adapt,scale,2); 596 if (scale != PETSC_DEFAULT && scale <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Scale factor %g must be positive",(double)scale); 597 if (scale != PETSC_DEFAULT && scale > 1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Scale factor %g must be less than one",(double)scale); 598 if (scale != PETSC_DEFAULT) adapt->scale_solve_failed = scale; 599 PetscFunctionReturn(0); 600 } 601 602 /*@ 603 TSAdaptGetScaleSolveFailed - Gets the admissible decrease/increase factor in step size 604 605 Not Collective 606 607 Input Arguments: 608 . adapt - adaptive controller context 609 610 Ouput Arguments: 611 . scale - scale factor 612 613 Level: intermediate 614 615 .seealso: TSAdaptChoose(), TSAdaptSetScaleSolveFailed(), TSAdaptSetClip() 616 @*/ 617 PetscErrorCode TSAdaptGetScaleSolveFailed(TSAdapt adapt,PetscReal *scale) 618 { 619 PetscFunctionBegin; 620 PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1); 621 if (scale) PetscValidRealPointer(scale,2); 622 if (scale) *scale = adapt->scale_solve_failed; 623 PetscFunctionReturn(0); 624 } 625 626 /*@ 627 TSAdaptSetStepLimits - Set the minimum and maximum step sizes to be considered by the controller 628 629 Logically collective on TSAdapt 630 631 Input Arguments: 632 + adapt - time step adaptivity context, usually gotten with TSGetAdapt() 633 . hmin - minimum time step 634 - hmax - maximum time step 635 636 Options Database Keys: 637 + -ts_adapt_dt_min <min> - to set minimum time step 638 - -ts_adapt_dt_max <max> - to set maximum time step 639 640 Level: intermediate 641 642 .seealso: TSAdapt, TSAdaptGetStepLimits(), TSAdaptChoose() 643 @*/ 644 PetscErrorCode TSAdaptSetStepLimits(TSAdapt adapt,PetscReal hmin,PetscReal hmax) 645 { 646 647 PetscFunctionBegin; 648 PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1); 649 PetscValidLogicalCollectiveReal(adapt,hmin,2); 650 PetscValidLogicalCollectiveReal(adapt,hmax,3); 651 if (hmin != PETSC_DEFAULT && hmin < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Minimum time step %g must be non negative",(double)hmin); 652 if (hmax != PETSC_DEFAULT && hmax < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Minimum time step %g must be non negative",(double)hmax); 653 if (hmin != PETSC_DEFAULT) adapt->dt_min = hmin; 654 if (hmax != PETSC_DEFAULT) adapt->dt_max = hmax; 655 hmin = adapt->dt_min; 656 hmax = adapt->dt_max; 657 if (hmax <= hmin) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Maximum time step %g must greater than minimum time step %g",(double)hmax,(double)hmin); 658 PetscFunctionReturn(0); 659 } 660 661 /*@ 662 TSAdaptGetStepLimits - Get the minimum and maximum step sizes to be considered by the controller 663 664 Not Collective 665 666 Input Arguments: 667 . adapt - time step adaptivity context, usually gotten with TSGetAdapt() 668 669 Output Arguments: 670 + hmin - minimum time step 671 - hmax - maximum time step 672 673 Level: intermediate 674 675 .seealso: TSAdapt, TSAdaptSetStepLimits(), TSAdaptChoose() 676 @*/ 677 PetscErrorCode TSAdaptGetStepLimits(TSAdapt adapt,PetscReal *hmin,PetscReal *hmax) 678 { 679 680 PetscFunctionBegin; 681 PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1); 682 if (hmin) PetscValidRealPointer(hmin,2); 683 if (hmax) PetscValidRealPointer(hmax,3); 684 if (hmin) *hmin = adapt->dt_min; 685 if (hmax) *hmax = adapt->dt_max; 686 PetscFunctionReturn(0); 687 } 688 689 /* 690 TSAdaptSetFromOptions - Sets various TSAdapt parameters from user options. 691 692 Collective on TSAdapt 693 694 Input Parameter: 695 . adapt - the TSAdapt context 696 697 Options Database Keys: 698 + -ts_adapt_type <type> - algorithm to use for adaptivity 699 . -ts_adapt_always_accept - always accept steps regardless of error/stability goals 700 . -ts_adapt_safety <safety> - safety factor relative to target error/stability goal 701 . -ts_adapt_reject_safety <safety> - extra safety factor to apply if the last step was rejected 702 . -ts_adapt_clip <low,high> - admissible time step decrease and increase factors 703 . -ts_adapt_dt_min <min> - minimum timestep to use 704 . -ts_adapt_dt_max <max> - maximum timestep to use 705 . -ts_adapt_scale_solve_failed <scale> - scale timestep by this factor if a solve fails 706 . -ts_adapt_wnormtype <2 or infinity> - type of norm for computing error estimates 707 - -ts_adapt_time_step_increase_delay - number of timesteps to delay increasing the time step after it has been decreased due to failed solver 708 709 Level: advanced 710 711 Notes: 712 This function is automatically called by TSSetFromOptions() 713 714 .seealso: TSGetAdapt(), TSAdaptSetType(), TSAdaptSetAlwaysAccept(), TSAdaptSetSafety(), 715 TSAdaptSetClip(), TSAdaptSetScaleSolveFailed(), TSAdaptSetStepLimits(), TSAdaptSetMonitor() 716 */ 717 PetscErrorCode TSAdaptSetFromOptions(PetscOptionItems *PetscOptionsObject,TSAdapt adapt) 718 { 719 PetscErrorCode ierr; 720 char type[256] = TSADAPTBASIC; 721 PetscReal safety,reject_safety,clip[2],scale,hmin,hmax; 722 PetscBool set,flg; 723 PetscInt two; 724 725 PetscFunctionBegin; 726 PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,2); 727 /* This should use PetscOptionsBegin() if/when this becomes an object used outside of TS, but currently this 728 * function can only be called from inside TSSetFromOptions() */ 729 ierr = PetscOptionsHead(PetscOptionsObject,"TS Adaptivity options");CHKERRQ(ierr); 730 ierr = PetscOptionsFList("-ts_adapt_type","Algorithm to use for adaptivity","TSAdaptSetType",TSAdaptList,((PetscObject)adapt)->type_name ? ((PetscObject)adapt)->type_name : type,type,sizeof(type),&flg);CHKERRQ(ierr); 731 if (flg || !((PetscObject)adapt)->type_name) { 732 ierr = TSAdaptSetType(adapt,type);CHKERRQ(ierr); 733 } 734 735 ierr = PetscOptionsBool("-ts_adapt_always_accept","Always accept the step","TSAdaptSetAlwaysAccept",adapt->always_accept,&flg,&set);CHKERRQ(ierr); 736 if (set) {ierr = TSAdaptSetAlwaysAccept(adapt,flg);CHKERRQ(ierr);} 737 738 safety = adapt->safety; reject_safety = adapt->reject_safety; 739 ierr = PetscOptionsReal("-ts_adapt_safety","Safety factor relative to target error/stability goal","TSAdaptSetSafety",safety,&safety,&set);CHKERRQ(ierr); 740 ierr = PetscOptionsReal("-ts_adapt_reject_safety","Extra safety factor to apply if the last step was rejected","TSAdaptSetSafety",reject_safety,&reject_safety,&flg);CHKERRQ(ierr); 741 if (set || flg) {ierr = TSAdaptSetSafety(adapt,safety,reject_safety);CHKERRQ(ierr);} 742 743 two = 2; clip[0] = adapt->clip[0]; clip[1] = adapt->clip[1]; 744 ierr = PetscOptionsRealArray("-ts_adapt_clip","Admissible decrease/increase factor in step size","TSAdaptSetClip",clip,&two,&set);CHKERRQ(ierr); 745 if (set && (two != 2)) SETERRQ(PetscObjectComm((PetscObject)adapt),PETSC_ERR_ARG_OUTOFRANGE,"Must give exactly two values to -ts_adapt_clip"); 746 if (set) {ierr = TSAdaptSetClip(adapt,clip[0],clip[1]);CHKERRQ(ierr);} 747 748 hmin = adapt->dt_min; hmax = adapt->dt_max; 749 ierr = PetscOptionsReal("-ts_adapt_dt_min","Minimum time step considered","TSAdaptSetStepLimits",hmin,&hmin,&set);CHKERRQ(ierr); 750 ierr = PetscOptionsReal("-ts_adapt_dt_max","Maximum time step considered","TSAdaptSetStepLimits",hmax,&hmax,&flg);CHKERRQ(ierr); 751 if (set || flg) {ierr = TSAdaptSetStepLimits(adapt,hmin,hmax);CHKERRQ(ierr);} 752 753 ierr = PetscOptionsReal("-ts_adapt_max_ignore","Adaptor ignores (absolute) solution values smaller than this value","",adapt->ignore_max,&adapt->ignore_max,&set);CHKERRQ(ierr); 754 ierr = PetscOptionsBool("-ts_adapt_glee_use_local","GLEE adaptor uses local error estimation for step control","",adapt->glee_use_local,&adapt->glee_use_local,&set);CHKERRQ(ierr); 755 756 ierr = PetscOptionsReal("-ts_adapt_scale_solve_failed","Scale step by this factor if solve fails","TSAdaptSetScaleSolveFailed",adapt->scale_solve_failed,&scale,&set);CHKERRQ(ierr); 757 if (set) {ierr = TSAdaptSetScaleSolveFailed(adapt,scale);CHKERRQ(ierr);} 758 759 ierr = PetscOptionsEnum("-ts_adapt_wnormtype","Type of norm computed for error estimation","",NormTypes,(PetscEnum)adapt->wnormtype,(PetscEnum*)&adapt->wnormtype,NULL);CHKERRQ(ierr); 760 if (adapt->wnormtype != NORM_2 && adapt->wnormtype != NORM_INFINITY) SETERRQ(PetscObjectComm((PetscObject)adapt),PETSC_ERR_SUP,"Only 2-norm and infinite norm supported"); 761 762 ierr = PetscOptionsInt("-ts_adapt_time_step_increase_delay","Number of timesteps to delay increasing the time step after it has been decreased due to failed solver","TSAdaptSetTimeStepIncreaseDelay",adapt->timestepjustdecreased_delay,&adapt->timestepjustdecreased_delay,NULL);CHKERRQ(ierr); 763 764 ierr = PetscOptionsBool("-ts_adapt_monitor","Print choices made by adaptive controller","TSAdaptSetMonitor",adapt->monitor ? PETSC_TRUE : PETSC_FALSE,&flg,&set);CHKERRQ(ierr); 765 if (set) {ierr = TSAdaptSetMonitor(adapt,flg);CHKERRQ(ierr);} 766 767 if (adapt->ops->setfromoptions) {ierr = (*adapt->ops->setfromoptions)(PetscOptionsObject,adapt);CHKERRQ(ierr);} 768 ierr = PetscOptionsTail();CHKERRQ(ierr); 769 PetscFunctionReturn(0); 770 } 771 772 /*@ 773 TSAdaptCandidatesClear - clear any previously set candidate schemes 774 775 Logically collective on TSAdapt 776 777 Input Argument: 778 . adapt - adaptive controller 779 780 Level: developer 781 782 .seealso: TSAdapt, TSAdaptCreate(), TSAdaptCandidateAdd(), TSAdaptChoose() 783 @*/ 784 PetscErrorCode TSAdaptCandidatesClear(TSAdapt adapt) 785 { 786 PetscErrorCode ierr; 787 788 PetscFunctionBegin; 789 PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1); 790 ierr = PetscMemzero(&adapt->candidates,sizeof(adapt->candidates));CHKERRQ(ierr); 791 PetscFunctionReturn(0); 792 } 793 794 /*@C 795 TSAdaptCandidateAdd - add a candidate scheme for the adaptive controller to select from 796 797 Logically collective on TSAdapt 798 799 Input Arguments: 800 + adapt - time step adaptivity context, obtained with TSGetAdapt() or TSAdaptCreate() 801 . name - name of the candidate scheme to add 802 . order - order of the candidate scheme 803 . stageorder - stage order of the candidate scheme 804 . ccfl - stability coefficient relative to explicit Euler, used for CFL constraints 805 . cost - relative measure of the amount of work required for the candidate scheme 806 - inuse - indicates that this scheme is the one currently in use, this flag can only be set for one scheme 807 808 Note: 809 This routine is not available in Fortran. 810 811 Level: developer 812 813 .seealso: TSAdaptCandidatesClear(), TSAdaptChoose() 814 @*/ 815 PetscErrorCode TSAdaptCandidateAdd(TSAdapt adapt,const char name[],PetscInt order,PetscInt stageorder,PetscReal ccfl,PetscReal cost,PetscBool inuse) 816 { 817 PetscInt c; 818 819 PetscFunctionBegin; 820 PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1); 821 if (order < 1) SETERRQ1(PetscObjectComm((PetscObject)adapt),PETSC_ERR_ARG_OUTOFRANGE,"Classical order %D must be a positive integer",order); 822 if (inuse) { 823 if (adapt->candidates.inuse_set) SETERRQ(PetscObjectComm((PetscObject)adapt),PETSC_ERR_ARG_WRONGSTATE,"Cannot set the inuse method twice, maybe forgot to call TSAdaptCandidatesClear()"); 824 adapt->candidates.inuse_set = PETSC_TRUE; 825 } 826 /* first slot if this is the current scheme, otherwise the next available slot */ 827 c = inuse ? 0 : !adapt->candidates.inuse_set + adapt->candidates.n; 828 829 adapt->candidates.name[c] = name; 830 adapt->candidates.order[c] = order; 831 adapt->candidates.stageorder[c] = stageorder; 832 adapt->candidates.ccfl[c] = ccfl; 833 adapt->candidates.cost[c] = cost; 834 adapt->candidates.n++; 835 PetscFunctionReturn(0); 836 } 837 838 /*@C 839 TSAdaptCandidatesGet - Get the list of candidate orders of accuracy and cost 840 841 Not Collective 842 843 Input Arguments: 844 . adapt - time step adaptivity context 845 846 Output Arguments: 847 + n - number of candidate schemes, always at least 1 848 . order - the order of each candidate scheme 849 . stageorder - the stage order of each candidate scheme 850 . ccfl - the CFL coefficient of each scheme 851 - cost - the relative cost of each scheme 852 853 Level: developer 854 855 Note: 856 The current scheme is always returned in the first slot 857 858 .seealso: TSAdaptCandidatesClear(), TSAdaptCandidateAdd(), TSAdaptChoose() 859 @*/ 860 PetscErrorCode TSAdaptCandidatesGet(TSAdapt adapt,PetscInt *n,const PetscInt **order,const PetscInt **stageorder,const PetscReal **ccfl,const PetscReal **cost) 861 { 862 PetscFunctionBegin; 863 PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1); 864 if (n) *n = adapt->candidates.n; 865 if (order) *order = adapt->candidates.order; 866 if (stageorder) *stageorder = adapt->candidates.stageorder; 867 if (ccfl) *ccfl = adapt->candidates.ccfl; 868 if (cost) *cost = adapt->candidates.cost; 869 PetscFunctionReturn(0); 870 } 871 872 /*@C 873 TSAdaptChoose - choose which method and step size to use for the next step 874 875 Collective on TSAdapt 876 877 Input Arguments: 878 + adapt - adaptive contoller 879 - h - current step size 880 881 Output Arguments: 882 + next_sc - optional, scheme to use for the next step 883 . next_h - step size to use for the next step 884 - accept - PETSC_TRUE to accept the current step, PETSC_FALSE to repeat the current step with the new step size 885 886 Note: 887 The input value of parameter accept is retained from the last time step, so it will be PETSC_FALSE if the step is 888 being retried after an initial rejection. 889 890 Level: developer 891 892 .seealso: TSAdapt, TSAdaptCandidatesClear(), TSAdaptCandidateAdd() 893 @*/ 894 PetscErrorCode TSAdaptChoose(TSAdapt adapt,TS ts,PetscReal h,PetscInt *next_sc,PetscReal *next_h,PetscBool *accept) 895 { 896 PetscErrorCode ierr; 897 PetscInt ncandidates = adapt->candidates.n; 898 PetscInt scheme = 0; 899 PetscReal wlte = -1.0; 900 PetscReal wltea = -1.0; 901 PetscReal wlter = -1.0; 902 903 PetscFunctionBegin; 904 PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1); 905 PetscValidHeaderSpecific(ts,TS_CLASSID,2); 906 if (next_sc) PetscValidIntPointer(next_sc,4); 907 PetscValidPointer(next_h,5); 908 PetscValidBoolPointer(accept,6); 909 if (next_sc) *next_sc = 0; 910 911 /* Do not mess with adaptivity while handling events*/ 912 if (ts->event && ts->event->status != TSEVENT_NONE) { 913 *next_h = h; 914 *accept = PETSC_TRUE; 915 PetscFunctionReturn(0); 916 } 917 918 ierr = (*adapt->ops->choose)(adapt,ts,h,&scheme,next_h,accept,&wlte,&wltea,&wlter);CHKERRQ(ierr); 919 if (scheme < 0 || (ncandidates > 0 && scheme >= ncandidates)) SETERRQ2(PetscObjectComm((PetscObject)adapt),PETSC_ERR_ARG_OUTOFRANGE,"Chosen scheme %D not in valid range 0..%D",scheme,ncandidates-1); 920 if (*next_h < 0) SETERRQ1(PetscObjectComm((PetscObject)adapt),PETSC_ERR_ARG_OUTOFRANGE,"Computed step size %g must be positive",(double)*next_h); 921 if (next_sc) *next_sc = scheme; 922 923 if (*accept && ts->exact_final_time == TS_EXACTFINALTIME_MATCHSTEP) { 924 /* Increase/reduce step size if end time of next step is close to or overshoots max time */ 925 PetscReal t = ts->ptime + ts->time_step, h = *next_h; 926 PetscReal tend = t + h, tmax = ts->max_time, hmax = tmax - t; 927 PetscReal a = (PetscReal)(1.0 + adapt->matchstepfac[0]); 928 PetscReal b = adapt->matchstepfac[1]; 929 if (t < tmax && tend > tmax) *next_h = hmax; 930 if (t < tmax && tend < tmax && h*b > hmax) *next_h = hmax/2; 931 if (t < tmax && tend < tmax && h*a > hmax) *next_h = hmax; 932 } 933 934 if (adapt->monitor) { 935 const char *sc_name = (scheme < ncandidates) ? adapt->candidates.name[scheme] : ""; 936 ierr = PetscViewerASCIIAddTab(adapt->monitor,((PetscObject)adapt)->tablevel);CHKERRQ(ierr); 937 if (wlte < 0) { 938 ierr = PetscViewerASCIIPrintf(adapt->monitor," TSAdapt %s %s %D:%s step %3D %s t=%-11g+%10.3e dt=%-10.3e\n",((PetscObject)adapt)->type_name,((PetscObject)ts)->type_name,scheme,sc_name,ts->steps,*accept ? "accepted" : "rejected",(double)ts->ptime,(double)h,(double)*next_h);CHKERRQ(ierr); 939 } else { 940 ierr = PetscViewerASCIIPrintf(adapt->monitor," TSAdapt %s %s %D:%s step %3D %s t=%-11g+%10.3e dt=%-10.3e wlte=%5.3g wltea=%5.3g wlter=%5.3g\n",((PetscObject)adapt)->type_name,((PetscObject)ts)->type_name,scheme,sc_name,ts->steps,*accept ? "accepted" : "rejected",(double)ts->ptime,(double)h,(double)*next_h,(double)wlte,(double)wltea,(double)wlter);CHKERRQ(ierr); 941 } 942 ierr = PetscViewerASCIISubtractTab(adapt->monitor,((PetscObject)adapt)->tablevel);CHKERRQ(ierr); 943 } 944 PetscFunctionReturn(0); 945 } 946 947 /*@ 948 TSAdaptSetTimeStepIncreaseDelay - The number of timesteps to wait after a decrease in the timestep due to failed solver 949 before increasing the time step. 950 951 Logicially Collective on TSAdapt 952 953 Input Arguments: 954 + adapt - adaptive controller context 955 - cnt - the number of timesteps 956 957 Options Database Key: 958 . -ts_adapt_time_step_increase_delay cnt - number of steps to delay the increase 959 960 Notes: This is to prevent an adaptor from bouncing back and forth between two nearby timesteps. The default is 0. 961 The successful use of this option is problem dependent 962 963 Developer Note: there is no theory to support this option 964 965 Level: advanced 966 967 .seealso: 968 @*/ 969 PetscErrorCode TSAdaptSetTimeStepIncreaseDelay(TSAdapt adapt,PetscInt cnt) 970 { 971 PetscFunctionBegin; 972 adapt->timestepjustdecreased_delay = cnt; 973 PetscFunctionReturn(0); 974 } 975 976 /*@ 977 TSAdaptCheckStage - checks whether to accept a stage, (e.g. reject and change time step size if nonlinear solve fails or solution vector is infeasible) 978 979 Collective on TSAdapt 980 981 Input Arguments: 982 + adapt - adaptive controller context 983 . ts - time stepper 984 . t - Current simulation time 985 - Y - Current solution vector 986 987 Output Arguments: 988 . accept - PETSC_TRUE to accept the stage, PETSC_FALSE to reject 989 990 Level: developer 991 992 .seealso: 993 @*/ 994 PetscErrorCode TSAdaptCheckStage(TSAdapt adapt,TS ts,PetscReal t,Vec Y,PetscBool *accept) 995 { 996 PetscErrorCode ierr; 997 SNESConvergedReason snesreason = SNES_CONVERGED_ITERATING; 998 999 PetscFunctionBegin; 1000 PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1); 1001 PetscValidHeaderSpecific(ts,TS_CLASSID,2); 1002 PetscValidBoolPointer(accept,5); 1003 1004 if (ts->snes) {ierr = SNESGetConvergedReason(ts->snes,&snesreason);CHKERRQ(ierr);} 1005 if (snesreason < 0) { 1006 *accept = PETSC_FALSE; 1007 if (++ts->num_snes_failures >= ts->max_snes_failures && ts->max_snes_failures > 0) { 1008 ts->reason = TS_DIVERGED_NONLINEAR_SOLVE; 1009 ierr = PetscInfo2(ts,"Step=%D, nonlinear solve failures %D greater than current TS allowed, stopping solve\n",ts->steps,ts->num_snes_failures);CHKERRQ(ierr); 1010 if (adapt->monitor) { 1011 ierr = PetscViewerASCIIAddTab(adapt->monitor,((PetscObject)adapt)->tablevel);CHKERRQ(ierr); 1012 ierr = PetscViewerASCIIPrintf(adapt->monitor," TSAdapt %s step %3D stage rejected t=%-11g+%10.3e, nonlinear solve failures %D greater than current TS allowed\n",((PetscObject)adapt)->type_name,ts->steps,(double)ts->ptime,(double)ts->time_step,ts->num_snes_failures);CHKERRQ(ierr); 1013 ierr = PetscViewerASCIISubtractTab(adapt->monitor,((PetscObject)adapt)->tablevel);CHKERRQ(ierr); 1014 } 1015 } 1016 } else { 1017 *accept = PETSC_TRUE; 1018 ierr = TSFunctionDomainError(ts,t,Y,accept);CHKERRQ(ierr); 1019 if (*accept && adapt->checkstage) { 1020 ierr = (*adapt->checkstage)(adapt,ts,t,Y,accept);CHKERRQ(ierr); 1021 if (!*accept) { 1022 ierr = PetscInfo1(ts,"Step=%D, solution rejected by user function provided by TSSetFunctionDomainError()\n",ts->steps);CHKERRQ(ierr); 1023 if (adapt->monitor) { 1024 ierr = PetscViewerASCIIAddTab(adapt->monitor,((PetscObject)adapt)->tablevel);CHKERRQ(ierr); 1025 ierr = PetscViewerASCIIPrintf(adapt->monitor," TSAdapt %s step %3D stage rejected by user function provided by TSSetFunctionDomainError()\n",((PetscObject)adapt)->type_name,ts->steps);CHKERRQ(ierr); 1026 ierr = PetscViewerASCIISubtractTab(adapt->monitor,((PetscObject)adapt)->tablevel);CHKERRQ(ierr); 1027 } 1028 } 1029 } 1030 } 1031 1032 if (!(*accept) && !ts->reason) { 1033 PetscReal dt,new_dt; 1034 ierr = TSGetTimeStep(ts,&dt);CHKERRQ(ierr); 1035 new_dt = dt * adapt->scale_solve_failed; 1036 ierr = TSSetTimeStep(ts,new_dt);CHKERRQ(ierr); 1037 adapt->timestepjustdecreased += adapt->timestepjustdecreased_delay; 1038 if (adapt->monitor) { 1039 ierr = PetscViewerASCIIAddTab(adapt->monitor,((PetscObject)adapt)->tablevel);CHKERRQ(ierr); 1040 ierr = PetscViewerASCIIPrintf(adapt->monitor," TSAdapt %s step %3D stage rejected (%s) t=%-11g+%10.3e retrying with dt=%-10.3e\n",((PetscObject)adapt)->type_name,ts->steps,SNESConvergedReasons[snesreason],(double)ts->ptime,(double)dt,(double)new_dt);CHKERRQ(ierr); 1041 ierr = PetscViewerASCIISubtractTab(adapt->monitor,((PetscObject)adapt)->tablevel);CHKERRQ(ierr); 1042 } 1043 } 1044 PetscFunctionReturn(0); 1045 } 1046 1047 /*@ 1048 TSAdaptCreate - create an adaptive controller context for time stepping 1049 1050 Collective 1051 1052 Input Parameter: 1053 . comm - The communicator 1054 1055 Output Parameter: 1056 . adapt - new TSAdapt object 1057 1058 Level: developer 1059 1060 Notes: 1061 TSAdapt creation is handled by TS, so users should not need to call this function. 1062 1063 .seealso: TSGetAdapt(), TSAdaptSetType(), TSAdaptDestroy() 1064 @*/ 1065 PetscErrorCode TSAdaptCreate(MPI_Comm comm,TSAdapt *inadapt) 1066 { 1067 PetscErrorCode ierr; 1068 TSAdapt adapt; 1069 1070 PetscFunctionBegin; 1071 PetscValidPointer(inadapt,2); 1072 *inadapt = NULL; 1073 ierr = TSAdaptInitializePackage();CHKERRQ(ierr); 1074 1075 ierr = PetscHeaderCreate(adapt,TSADAPT_CLASSID,"TSAdapt","Time stepping adaptivity","TS",comm,TSAdaptDestroy,TSAdaptView);CHKERRQ(ierr); 1076 1077 adapt->always_accept = PETSC_FALSE; 1078 adapt->safety = 0.9; 1079 adapt->reject_safety = 0.5; 1080 adapt->clip[0] = 0.1; 1081 adapt->clip[1] = 10.; 1082 adapt->dt_min = 1e-20; 1083 adapt->dt_max = 1e+20; 1084 adapt->ignore_max = -1.0; 1085 adapt->glee_use_local = PETSC_TRUE; 1086 adapt->scale_solve_failed = 0.25; 1087 /* these two safety factors are not public, and they are used only in the TS_EXACTFINALTIME_MATCHSTEP case 1088 to prevent from situations were unreasonably small time steps are taken in order to match the final time */ 1089 adapt->matchstepfac[0] = 0.01; /* allow 1% step size increase in the last step */ 1090 adapt->matchstepfac[1] = 2.0; /* halve last step if it is greater than what remains divided this factor */ 1091 adapt->wnormtype = NORM_2; 1092 adapt->timestepjustdecreased_delay = 0; 1093 1094 *inadapt = adapt; 1095 PetscFunctionReturn(0); 1096 } 1097