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,PETSC_FALSE);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 377 PetscFunctionBegin; 378 PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1); 379 adapt->checkstage = func; 380 PetscFunctionReturn(0); 381 } 382 383 /*@ 384 TSAdaptSetAlwaysAccept - Set whether to always accept steps regardless of 385 any error or stability condition not meeting the prescribed goal. 386 387 Logically collective on TSAdapt 388 389 Input Arguments: 390 + adapt - time step adaptivity context, usually gotten with TSGetAdapt() 391 - flag - whether to always accept steps 392 393 Options Database Keys: 394 . -ts_adapt_always_accept - to always accept steps 395 396 Level: intermediate 397 398 .seealso: TSAdapt, TSAdaptChoose() 399 @*/ 400 PetscErrorCode TSAdaptSetAlwaysAccept(TSAdapt adapt,PetscBool flag) 401 { 402 PetscFunctionBegin; 403 PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1); 404 PetscValidLogicalCollectiveBool(adapt,flag,2); 405 adapt->always_accept = flag; 406 PetscFunctionReturn(0); 407 } 408 409 /*@ 410 TSAdaptSetSafety - Set safety factors 411 412 Logically collective on TSAdapt 413 414 Input Arguments: 415 + adapt - adaptive controller context 416 . safety - safety factor relative to target error/stability goal 417 - reject_safety - extra safety factor to apply if the last step was rejected 418 419 Options Database Keys: 420 + -ts_adapt_safety <safety> - to set safety factor 421 - -ts_adapt_reject_safety <reject_safety> - to set reject safety factor 422 423 Level: intermediate 424 425 .seealso: TSAdapt, TSAdaptGetSafety(), TSAdaptChoose() 426 @*/ 427 PetscErrorCode TSAdaptSetSafety(TSAdapt adapt,PetscReal safety,PetscReal reject_safety) 428 { 429 PetscFunctionBegin; 430 PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1); 431 PetscValidLogicalCollectiveReal(adapt,safety,2); 432 PetscValidLogicalCollectiveReal(adapt,reject_safety,3); 433 if (safety != PETSC_DEFAULT && safety < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Safety factor %g must be non negative",(double)safety); 434 if (safety != PETSC_DEFAULT && safety > 1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Safety factor %g must be less than one",(double)safety); 435 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); 436 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); 437 if (safety != PETSC_DEFAULT) adapt->safety = safety; 438 if (reject_safety != PETSC_DEFAULT) adapt->reject_safety = reject_safety; 439 PetscFunctionReturn(0); 440 } 441 442 /*@ 443 TSAdaptGetSafety - Get safety factors 444 445 Not Collective 446 447 Input Arguments: 448 . adapt - adaptive controller context 449 450 Ouput Arguments: 451 . safety - safety factor relative to target error/stability goal 452 + reject_safety - extra safety factor to apply if the last step was rejected 453 454 Level: intermediate 455 456 .seealso: TSAdapt, TSAdaptSetSafety(), TSAdaptChoose() 457 @*/ 458 PetscErrorCode TSAdaptGetSafety(TSAdapt adapt,PetscReal *safety,PetscReal *reject_safety) 459 { 460 PetscFunctionBegin; 461 PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1); 462 if (safety) PetscValidRealPointer(safety,2); 463 if (reject_safety) PetscValidRealPointer(reject_safety,3); 464 if (safety) *safety = adapt->safety; 465 if (reject_safety) *reject_safety = adapt->reject_safety; 466 PetscFunctionReturn(0); 467 } 468 469 /*@ 470 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. 471 472 Logically collective on TSAdapt 473 474 Input Arguments: 475 + adapt - adaptive controller context 476 - max_ignore - threshold for solution components that are ignored during error estimation 477 478 Options Database Keys: 479 . -ts_adapt_max_ignore <max_ignore> - to set the threshold 480 481 Level: intermediate 482 483 .seealso: TSAdapt, TSAdaptGetMaxIgnore(), TSAdaptChoose() 484 @*/ 485 PetscErrorCode TSAdaptSetMaxIgnore(TSAdapt adapt,PetscReal max_ignore) 486 { 487 PetscFunctionBegin; 488 PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1); 489 PetscValidLogicalCollectiveReal(adapt,max_ignore,2); 490 adapt->ignore_max = max_ignore; 491 PetscFunctionReturn(0); 492 } 493 494 /*@ 495 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). 496 497 Not Collective 498 499 Input Arguments: 500 . adapt - adaptive controller context 501 502 Ouput Arguments: 503 . max_ignore - threshold for solution components that are ignored during error estimation 504 505 Level: intermediate 506 507 .seealso: TSAdapt, TSAdaptSetMaxIgnore(), TSAdaptChoose() 508 @*/ 509 PetscErrorCode TSAdaptGetMaxIgnore(TSAdapt adapt,PetscReal *max_ignore) 510 { 511 PetscFunctionBegin; 512 PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1); 513 PetscValidRealPointer(max_ignore,2); 514 *max_ignore = adapt->ignore_max; 515 PetscFunctionReturn(0); 516 } 517 518 519 /*@ 520 TSAdaptSetClip - Sets the admissible decrease/increase factor in step size 521 522 Logically collective on TSAdapt 523 524 Input Arguments: 525 + adapt - adaptive controller context 526 . low - admissible decrease factor 527 - high - admissible increase factor 528 529 Options Database Keys: 530 . -ts_adapt_clip <low>,<high> - to set admissible time step decrease and increase factors 531 532 Level: intermediate 533 534 .seealso: TSAdaptChoose(), TSAdaptGetClip() 535 @*/ 536 PetscErrorCode TSAdaptSetClip(TSAdapt adapt,PetscReal low,PetscReal high) 537 { 538 PetscFunctionBegin; 539 PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1); 540 PetscValidLogicalCollectiveReal(adapt,low,2); 541 PetscValidLogicalCollectiveReal(adapt,high,3); 542 if (low != PETSC_DEFAULT && low < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Decrease factor %g must be non negative",(double)low); 543 if (low != PETSC_DEFAULT && low > 1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Decrease factor %g must be less than one",(double)low); 544 if (high != PETSC_DEFAULT && high < 1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Increase factor %g must be geather than one",(double)high); 545 if (low != PETSC_DEFAULT) adapt->clip[0] = low; 546 if (high != PETSC_DEFAULT) adapt->clip[1] = high; 547 PetscFunctionReturn(0); 548 } 549 550 /*@ 551 TSAdaptGetClip - Gets the admissible decrease/increase factor in step size 552 553 Not Collective 554 555 Input Arguments: 556 . adapt - adaptive controller context 557 558 Ouput Arguments: 559 + low - optional, admissible decrease factor 560 - high - optional, admissible increase factor 561 562 Level: intermediate 563 564 .seealso: TSAdaptChoose(), TSAdaptSetClip() 565 @*/ 566 PetscErrorCode TSAdaptGetClip(TSAdapt adapt,PetscReal *low,PetscReal *high) 567 { 568 PetscFunctionBegin; 569 PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1); 570 if (low) PetscValidRealPointer(low,2); 571 if (high) PetscValidRealPointer(high,3); 572 if (low) *low = adapt->clip[0]; 573 if (high) *high = adapt->clip[1]; 574 PetscFunctionReturn(0); 575 } 576 577 /*@ 578 TSAdaptSetStepLimits - Set the minimum and maximum step sizes to be considered by the controller 579 580 Logically collective on TSAdapt 581 582 Input Arguments: 583 + adapt - time step adaptivity context, usually gotten with TSGetAdapt() 584 . hmin - minimum time step 585 - hmax - maximum time step 586 587 Options Database Keys: 588 + -ts_adapt_dt_min <min> - to set minimum time step 589 - -ts_adapt_dt_max <max> - to set maximum time step 590 591 Level: intermediate 592 593 .seealso: TSAdapt, TSAdaptGetStepLimits(), TSAdaptChoose() 594 @*/ 595 PetscErrorCode TSAdaptSetStepLimits(TSAdapt adapt,PetscReal hmin,PetscReal hmax) 596 { 597 598 PetscFunctionBegin; 599 PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1); 600 PetscValidLogicalCollectiveReal(adapt,hmin,2); 601 PetscValidLogicalCollectiveReal(adapt,hmax,3); 602 if (hmin != PETSC_DEFAULT && hmin < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Minimum time step %g must be non negative",(double)hmin); 603 if (hmax != PETSC_DEFAULT && hmax < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Minimum time step %g must be non negative",(double)hmax); 604 if (hmin != PETSC_DEFAULT) adapt->dt_min = hmin; 605 if (hmax != PETSC_DEFAULT) adapt->dt_max = hmax; 606 hmin = adapt->dt_min; 607 hmax = adapt->dt_max; 608 if (hmax <= hmin) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Maximum time step %g must geather than minimum time step %g",(double)hmax,(double)hmin); 609 PetscFunctionReturn(0); 610 } 611 612 /*@ 613 TSAdaptGetStepLimits - Get the minimum and maximum step sizes to be considered by the controller 614 615 Not Collective 616 617 Input Arguments: 618 . adapt - time step adaptivity context, usually gotten with TSGetAdapt() 619 620 Output Arguments: 621 + hmin - minimum time step 622 - hmax - maximum time step 623 624 Level: intermediate 625 626 .seealso: TSAdapt, TSAdaptSetStepLimits(), TSAdaptChoose() 627 @*/ 628 PetscErrorCode TSAdaptGetStepLimits(TSAdapt adapt,PetscReal *hmin,PetscReal *hmax) 629 { 630 631 PetscFunctionBegin; 632 PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1); 633 if (hmin) PetscValidRealPointer(hmin,2); 634 if (hmax) PetscValidRealPointer(hmax,3); 635 if (hmin) *hmin = adapt->dt_min; 636 if (hmax) *hmax = adapt->dt_max; 637 PetscFunctionReturn(0); 638 } 639 640 /* 641 TSAdaptSetFromOptions - Sets various TSAdapt parameters from user options. 642 643 Collective on TSAdapt 644 645 Input Parameter: 646 . adapt - the TSAdapt context 647 648 Options Database Keys: 649 + -ts_adapt_type <type> - algorithm to use for adaptivity 650 . -ts_adapt_always_accept - always accept steps regardless of error/stability goals 651 . -ts_adapt_safety <safety> - safety factor relative to target error/stability goal 652 . -ts_adapt_reject_safety <safety> - extra safety factor to apply if the last step was rejected 653 . -ts_adapt_clip <low,high> - admissible time step decrease and increase factors 654 . -ts_adapt_dt_min <min> - minimum timestep to use 655 . -ts_adapt_dt_max <max> - maximum timestep to use 656 . -ts_adapt_scale_solve_failed <scale> - scale timestep by this factor if a solve fails 657 . -ts_adapt_wnormtype <2 or infinity> - type of norm for computing error estimates 658 - -ts_adapt_time_step_increase_delay - number of timesteps to delay increasing the time step after it has been decreased due to failed solver 659 660 Level: advanced 661 662 Notes: 663 This function is automatically called by TSSetFromOptions() 664 665 .seealso: TSGetAdapt(), TSAdaptSetType(), TSAdaptSetAlwaysAccept(), TSAdaptSetSafety(), 666 TSAdaptSetClip(), TSAdaptSetStepLimits(), TSAdaptSetMonitor() 667 */ 668 PetscErrorCode TSAdaptSetFromOptions(PetscOptionItems *PetscOptionsObject,TSAdapt adapt) 669 { 670 PetscErrorCode ierr; 671 char type[256] = TSADAPTBASIC; 672 PetscReal safety,reject_safety,clip[2],hmin,hmax; 673 PetscBool set,flg; 674 PetscInt two; 675 676 PetscFunctionBegin; 677 PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1); 678 /* This should use PetscOptionsBegin() if/when this becomes an object used outside of TS, but currently this 679 * function can only be called from inside TSSetFromOptions() */ 680 ierr = PetscOptionsHead(PetscOptionsObject,"TS Adaptivity options");CHKERRQ(ierr); 681 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); 682 if (flg || !((PetscObject)adapt)->type_name) { 683 ierr = TSAdaptSetType(adapt,type);CHKERRQ(ierr); 684 } 685 686 ierr = PetscOptionsBool("-ts_adapt_always_accept","Always accept the step","TSAdaptSetAlwaysAccept",adapt->always_accept,&flg,&set);CHKERRQ(ierr); 687 if (set) {ierr = TSAdaptSetAlwaysAccept(adapt,flg);CHKERRQ(ierr);} 688 689 safety = adapt->safety; reject_safety = adapt->reject_safety; 690 ierr = PetscOptionsReal("-ts_adapt_safety","Safety factor relative to target error/stability goal","TSAdaptSetSafety",safety,&safety,&set);CHKERRQ(ierr); 691 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); 692 if (set || flg) {ierr = TSAdaptSetSafety(adapt,safety,reject_safety);CHKERRQ(ierr);} 693 694 two = 2; clip[0] = adapt->clip[0]; clip[1] = adapt->clip[1]; 695 ierr = PetscOptionsRealArray("-ts_adapt_clip","Admissible decrease/increase factor in step size","TSAdaptSetClip",clip,&two,&set);CHKERRQ(ierr); 696 if (set && (two != 2)) SETERRQ(PetscObjectComm((PetscObject)adapt),PETSC_ERR_ARG_OUTOFRANGE,"Must give exactly two values to -ts_adapt_clip"); 697 if (set) {ierr = TSAdaptSetClip(adapt,clip[0],clip[1]);CHKERRQ(ierr);} 698 699 hmin = adapt->dt_min; hmax = adapt->dt_max; 700 ierr = PetscOptionsReal("-ts_adapt_dt_min","Minimum time step considered","TSAdaptSetStepLimits",hmin,&hmin,&set);CHKERRQ(ierr); 701 ierr = PetscOptionsReal("-ts_adapt_dt_max","Maximum time step considered","TSAdaptSetStepLimits",hmax,&hmax,&flg);CHKERRQ(ierr); 702 if (set || flg) {ierr = TSAdaptSetStepLimits(adapt,hmin,hmax);CHKERRQ(ierr);} 703 704 ierr = PetscOptionsReal("-ts_adapt_max_ignore","Adaptor ignores (absolute) solution values smaller than this value","",adapt->ignore_max,&adapt->ignore_max,&set);CHKERRQ(ierr); 705 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); 706 707 ierr = PetscOptionsReal("-ts_adapt_scale_solve_failed","Scale step by this factor if solve fails","",adapt->scale_solve_failed,&adapt->scale_solve_failed,NULL);CHKERRQ(ierr); 708 709 ierr = PetscOptionsEnum("-ts_adapt_wnormtype","Type of norm computed for error estimation","",NormTypes,(PetscEnum)adapt->wnormtype,(PetscEnum*)&adapt->wnormtype,NULL);CHKERRQ(ierr); 710 if (adapt->wnormtype != NORM_2 && adapt->wnormtype != NORM_INFINITY) SETERRQ(PetscObjectComm((PetscObject)adapt),PETSC_ERR_SUP,"Only 2-norm and infinite norm supported"); 711 712 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); 713 714 ierr = PetscOptionsBool("-ts_adapt_monitor","Print choices made by adaptive controller","TSAdaptSetMonitor",adapt->monitor ? PETSC_TRUE : PETSC_FALSE,&flg,&set);CHKERRQ(ierr); 715 if (set) {ierr = TSAdaptSetMonitor(adapt,flg);CHKERRQ(ierr);} 716 717 if (adapt->ops->setfromoptions) {ierr = (*adapt->ops->setfromoptions)(PetscOptionsObject,adapt);CHKERRQ(ierr);} 718 ierr = PetscOptionsTail();CHKERRQ(ierr); 719 PetscFunctionReturn(0); 720 } 721 722 /*@ 723 TSAdaptCandidatesClear - clear any previously set candidate schemes 724 725 Logically collective on TSAdapt 726 727 Input Argument: 728 . adapt - adaptive controller 729 730 Level: developer 731 732 .seealso: TSAdapt, TSAdaptCreate(), TSAdaptCandidateAdd(), TSAdaptChoose() 733 @*/ 734 PetscErrorCode TSAdaptCandidatesClear(TSAdapt adapt) 735 { 736 PetscErrorCode ierr; 737 738 PetscFunctionBegin; 739 PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1); 740 ierr = PetscMemzero(&adapt->candidates,sizeof(adapt->candidates));CHKERRQ(ierr); 741 PetscFunctionReturn(0); 742 } 743 744 /*@C 745 TSAdaptCandidateAdd - add a candidate scheme for the adaptive controller to select from 746 747 Logically collective on TSAdapt 748 749 Input Arguments: 750 + adapt - time step adaptivity context, obtained with TSGetAdapt() or TSAdaptCreate() 751 . name - name of the candidate scheme to add 752 . order - order of the candidate scheme 753 . stageorder - stage order of the candidate scheme 754 . ccfl - stability coefficient relative to explicit Euler, used for CFL constraints 755 . cost - relative measure of the amount of work required for the candidate scheme 756 - inuse - indicates that this scheme is the one currently in use, this flag can only be set for one scheme 757 758 Note: 759 This routine is not available in Fortran. 760 761 Level: developer 762 763 .seealso: TSAdaptCandidatesClear(), TSAdaptChoose() 764 @*/ 765 PetscErrorCode TSAdaptCandidateAdd(TSAdapt adapt,const char name[],PetscInt order,PetscInt stageorder,PetscReal ccfl,PetscReal cost,PetscBool inuse) 766 { 767 PetscInt c; 768 769 PetscFunctionBegin; 770 PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1); 771 if (order < 1) SETERRQ1(PetscObjectComm((PetscObject)adapt),PETSC_ERR_ARG_OUTOFRANGE,"Classical order %D must be a positive integer",order); 772 if (inuse) { 773 if (adapt->candidates.inuse_set) SETERRQ(PetscObjectComm((PetscObject)adapt),PETSC_ERR_ARG_WRONGSTATE,"Cannot set the inuse method twice, maybe forgot to call TSAdaptCandidatesClear()"); 774 adapt->candidates.inuse_set = PETSC_TRUE; 775 } 776 /* first slot if this is the current scheme, otherwise the next available slot */ 777 c = inuse ? 0 : !adapt->candidates.inuse_set + adapt->candidates.n; 778 779 adapt->candidates.name[c] = name; 780 adapt->candidates.order[c] = order; 781 adapt->candidates.stageorder[c] = stageorder; 782 adapt->candidates.ccfl[c] = ccfl; 783 adapt->candidates.cost[c] = cost; 784 adapt->candidates.n++; 785 PetscFunctionReturn(0); 786 } 787 788 /*@C 789 TSAdaptCandidatesGet - Get the list of candidate orders of accuracy and cost 790 791 Not Collective 792 793 Input Arguments: 794 . adapt - time step adaptivity context 795 796 Output Arguments: 797 + n - number of candidate schemes, always at least 1 798 . order - the order of each candidate scheme 799 . stageorder - the stage order of each candidate scheme 800 . ccfl - the CFL coefficient of each scheme 801 - cost - the relative cost of each scheme 802 803 Level: developer 804 805 Note: 806 The current scheme is always returned in the first slot 807 808 .seealso: TSAdaptCandidatesClear(), TSAdaptCandidateAdd(), TSAdaptChoose() 809 @*/ 810 PetscErrorCode TSAdaptCandidatesGet(TSAdapt adapt,PetscInt *n,const PetscInt **order,const PetscInt **stageorder,const PetscReal **ccfl,const PetscReal **cost) 811 { 812 PetscFunctionBegin; 813 PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1); 814 if (n) *n = adapt->candidates.n; 815 if (order) *order = adapt->candidates.order; 816 if (stageorder) *stageorder = adapt->candidates.stageorder; 817 if (ccfl) *ccfl = adapt->candidates.ccfl; 818 if (cost) *cost = adapt->candidates.cost; 819 PetscFunctionReturn(0); 820 } 821 822 /*@C 823 TSAdaptChoose - choose which method and step size to use for the next step 824 825 Collective on TSAdapt 826 827 Input Arguments: 828 + adapt - adaptive contoller 829 - h - current step size 830 831 Output Arguments: 832 + next_sc - optional, scheme to use for the next step 833 . next_h - step size to use for the next step 834 - accept - PETSC_TRUE to accept the current step, PETSC_FALSE to repeat the current step with the new step size 835 836 Note: 837 The input value of parameter accept is retained from the last time step, so it will be PETSC_FALSE if the step is 838 being retried after an initial rejection. 839 840 Level: developer 841 842 .seealso: TSAdapt, TSAdaptCandidatesClear(), TSAdaptCandidateAdd() 843 @*/ 844 PetscErrorCode TSAdaptChoose(TSAdapt adapt,TS ts,PetscReal h,PetscInt *next_sc,PetscReal *next_h,PetscBool *accept) 845 { 846 PetscErrorCode ierr; 847 PetscInt ncandidates = adapt->candidates.n; 848 PetscInt scheme = 0; 849 PetscReal wlte = -1.0; 850 PetscReal wltea = -1.0; 851 PetscReal wlter = -1.0; 852 853 PetscFunctionBegin; 854 PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1); 855 PetscValidHeaderSpecific(ts,TS_CLASSID,2); 856 if (next_sc) PetscValidIntPointer(next_sc,4); 857 PetscValidPointer(next_h,5); 858 PetscValidIntPointer(accept,6); 859 if (next_sc) *next_sc = 0; 860 861 /* Do not mess with adaptivity while handling events*/ 862 if (ts->event && ts->event->status != TSEVENT_NONE) { 863 *next_h = h; 864 *accept = PETSC_TRUE; 865 PetscFunctionReturn(0); 866 } 867 868 ierr = (*adapt->ops->choose)(adapt,ts,h,&scheme,next_h,accept,&wlte,&wltea,&wlter);CHKERRQ(ierr); 869 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); 870 if (*next_h < 0) SETERRQ1(PetscObjectComm((PetscObject)adapt),PETSC_ERR_ARG_OUTOFRANGE,"Computed step size %g must be positive",(double)*next_h); 871 if (next_sc) *next_sc = scheme; 872 873 if (*accept && ts->exact_final_time == TS_EXACTFINALTIME_MATCHSTEP) { 874 /* Increase/reduce step size if end time of next step is close to or overshoots max time */ 875 PetscReal t = ts->ptime + ts->time_step, h = *next_h; 876 PetscReal tend = t + h, tmax = ts->max_time, hmax = tmax - t; 877 PetscReal a = (PetscReal)(1.0 + adapt->matchstepfac[0]); 878 PetscReal b = adapt->matchstepfac[1]; 879 if (t < tmax && tend > tmax) *next_h = hmax; 880 if (t < tmax && tend < tmax && h*b > hmax) *next_h = hmax/2; 881 if (t < tmax && tend < tmax && h*a > hmax) *next_h = hmax; 882 } 883 884 if (adapt->monitor) { 885 const char *sc_name = (scheme < ncandidates) ? adapt->candidates.name[scheme] : ""; 886 ierr = PetscViewerASCIIAddTab(adapt->monitor,((PetscObject)adapt)->tablevel);CHKERRQ(ierr); 887 if (wlte < 0) { 888 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); 889 } else { 890 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); 891 } 892 ierr = PetscViewerASCIISubtractTab(adapt->monitor,((PetscObject)adapt)->tablevel);CHKERRQ(ierr); 893 } 894 PetscFunctionReturn(0); 895 } 896 897 /*@ 898 TSAdaptSetTimeStepIncreaseDelay - The number of timesteps to wait after a decrease in the timestep due to failed solver 899 before increasing the time step. 900 901 Logicially Collective on TSAdapt 902 903 Input Arguments: 904 + adapt - adaptive controller context 905 - cnt - the number of timesteps 906 907 Options Database Key: 908 . -ts_adapt_time_step_increase_delay cnt - number of steps to delay the increase 909 910 Notes: This is to prevent an adaptor from bouncing back and forth between two nearby timesteps. The default is 0. 911 The successful use of this option is problem dependent 912 913 Developer Note: there is no theory to support this option 914 915 Level: advanced 916 917 .seealso: 918 @*/ 919 PetscErrorCode TSAdaptSetTimeStepIncreaseDelay(TSAdapt adapt,PetscInt cnt) 920 { 921 PetscFunctionBegin; 922 adapt->timestepjustdecreased_delay = cnt; 923 PetscFunctionReturn(0); 924 } 925 926 927 /*@ 928 TSAdaptCheckStage - checks whether to accept a stage, (e.g. reject and change time step size if nonlinear solve fails) 929 930 Collective on TSAdapt 931 932 Input Arguments: 933 + adapt - adaptive controller context 934 . ts - time stepper 935 . t - Current simulation time 936 - Y - Current solution vector 937 938 Output Arguments: 939 . accept - PETSC_TRUE to accept the stage, PETSC_FALSE to reject 940 941 Level: developer 942 943 .seealso: 944 @*/ 945 PetscErrorCode TSAdaptCheckStage(TSAdapt adapt,TS ts,PetscReal t,Vec Y,PetscBool *accept) 946 { 947 PetscErrorCode ierr; 948 SNESConvergedReason snesreason = SNES_CONVERGED_ITERATING; 949 950 PetscFunctionBegin; 951 PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1); 952 PetscValidHeaderSpecific(ts,TS_CLASSID,2); 953 PetscValidIntPointer(accept,3); 954 955 if (ts->snes) {ierr = SNESGetConvergedReason(ts->snes,&snesreason);CHKERRQ(ierr);} 956 if (snesreason < 0) { 957 *accept = PETSC_FALSE; 958 if (++ts->num_snes_failures >= ts->max_snes_failures && ts->max_snes_failures > 0) { 959 ts->reason = TS_DIVERGED_NONLINEAR_SOLVE; 960 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); 961 if (adapt->monitor) { 962 ierr = PetscViewerASCIIAddTab(adapt->monitor,((PetscObject)adapt)->tablevel);CHKERRQ(ierr); 963 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); 964 ierr = PetscViewerASCIISubtractTab(adapt->monitor,((PetscObject)adapt)->tablevel);CHKERRQ(ierr); 965 } 966 } 967 } else { 968 *accept = PETSC_TRUE; 969 ierr = TSFunctionDomainError(ts,t,Y,accept);CHKERRQ(ierr); 970 if(*accept && adapt->checkstage) { 971 ierr = (*adapt->checkstage)(adapt,ts,t,Y,accept);CHKERRQ(ierr); 972 } 973 } 974 975 if(!(*accept) && !ts->reason) { 976 PetscReal dt,new_dt; 977 ierr = TSGetTimeStep(ts,&dt);CHKERRQ(ierr); 978 new_dt = dt * adapt->scale_solve_failed; 979 ierr = TSSetTimeStep(ts,new_dt);CHKERRQ(ierr); 980 adapt->timestepjustdecreased += adapt->timestepjustdecreased_delay; 981 if (adapt->monitor) { 982 ierr = PetscViewerASCIIAddTab(adapt->monitor,((PetscObject)adapt)->tablevel);CHKERRQ(ierr); 983 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); 984 ierr = PetscViewerASCIISubtractTab(adapt->monitor,((PetscObject)adapt)->tablevel);CHKERRQ(ierr); 985 } 986 } 987 PetscFunctionReturn(0); 988 } 989 990 /*@ 991 TSAdaptCreate - create an adaptive controller context for time stepping 992 993 Collective on MPI_Comm 994 995 Input Parameter: 996 . comm - The communicator 997 998 Output Parameter: 999 . adapt - new TSAdapt object 1000 1001 Level: developer 1002 1003 Notes: 1004 TSAdapt creation is handled by TS, so users should not need to call this function. 1005 1006 .seealso: TSGetAdapt(), TSAdaptSetType(), TSAdaptDestroy() 1007 @*/ 1008 PetscErrorCode TSAdaptCreate(MPI_Comm comm,TSAdapt *inadapt) 1009 { 1010 PetscErrorCode ierr; 1011 TSAdapt adapt; 1012 1013 PetscFunctionBegin; 1014 PetscValidPointer(inadapt,1); 1015 *inadapt = NULL; 1016 ierr = TSAdaptInitializePackage();CHKERRQ(ierr); 1017 1018 ierr = PetscHeaderCreate(adapt,TSADAPT_CLASSID,"TSAdapt","Time stepping adaptivity","TS",comm,TSAdaptDestroy,TSAdaptView);CHKERRQ(ierr); 1019 1020 adapt->always_accept = PETSC_FALSE; 1021 adapt->safety = 0.9; 1022 adapt->reject_safety = 0.5; 1023 adapt->clip[0] = 0.1; 1024 adapt->clip[1] = 10.; 1025 adapt->dt_min = 1e-20; 1026 adapt->dt_max = 1e+20; 1027 adapt->ignore_max = -1.0; 1028 adapt->glee_use_local = PETSC_TRUE; 1029 adapt->scale_solve_failed = 0.25; 1030 /* these two safety factors are not public, and they are used only in the TS_EXACTFINALTIME_MATCHSTEP case 1031 to prevent from situations were unreasonably small time steps are taken in order to match the final time */ 1032 adapt->matchstepfac[0] = 0.01; /* allow 1% step size increase in the last step */ 1033 adapt->matchstepfac[1] = 2.0; /* halve last step if it is greater than what remains divided this factor */ 1034 adapt->wnormtype = NORM_2; 1035 adapt->timestepjustdecreased_delay = 0; 1036 1037 *inadapt = adapt; 1038 PetscFunctionReturn(0); 1039 } 1040