1 /* 2 Code for timestepping with additive Runge-Kutta IMEX method 3 4 Notes: 5 The general system is written as 6 7 F(t,U,Udot) = G(t,U) 8 9 where F represents the stiff part of the physics and G represents the non-stiff part. 10 11 */ 12 #include <petsc/private/tsimpl.h> /*I "petscts.h" I*/ 13 #include <petscdm.h> 14 15 static TSARKIMEXType TSARKIMEXDefault = TSARKIMEX3; 16 static PetscBool TSARKIMEXRegisterAllCalled; 17 static PetscBool TSARKIMEXPackageInitialized; 18 static PetscErrorCode TSExtrapolate_ARKIMEX(TS,PetscReal,Vec); 19 20 typedef struct _ARKTableau *ARKTableau; 21 struct _ARKTableau { 22 char *name; 23 PetscInt order; /* Classical approximation order of the method */ 24 PetscInt s; /* Number of stages */ 25 PetscBool stiffly_accurate; /* The implicit part is stiffly accurate*/ 26 PetscBool FSAL_implicit; /* The implicit part is FSAL*/ 27 PetscBool explicit_first_stage; /* The implicit part has an explicit first stage*/ 28 PetscInt pinterp; /* Interpolation order */ 29 PetscReal *At,*bt,*ct; /* Stiff tableau */ 30 PetscReal *A,*b,*c; /* Non-stiff tableau */ 31 PetscReal *bembedt,*bembed; /* Embedded formula of order one less (order-1) */ 32 PetscReal *binterpt,*binterp; /* Dense output formula */ 33 PetscReal ccfl; /* Placeholder for CFL coefficient relative to forward Euler */ 34 }; 35 typedef struct _ARKTableauLink *ARKTableauLink; 36 struct _ARKTableauLink { 37 struct _ARKTableau tab; 38 ARKTableauLink next; 39 }; 40 static ARKTableauLink ARKTableauList; 41 42 typedef struct { 43 ARKTableau tableau; 44 Vec *Y; /* States computed during the step */ 45 Vec *YdotI; /* Time derivatives for the stiff part */ 46 Vec *YdotRHS; /* Function evaluations for the non-stiff part */ 47 Vec *Y_prev; /* States computed during the previous time step */ 48 Vec *YdotI_prev; /* Time derivatives for the stiff part for the previous time step*/ 49 Vec *YdotRHS_prev; /* Function evaluations for the non-stiff part for the previous time step*/ 50 Vec Ydot0; /* Holds the slope from the previous step in FSAL case */ 51 Vec Ydot; /* Work vector holding Ydot during residual evaluation */ 52 Vec Z; /* Ydot = shift(Y-Z) */ 53 PetscScalar *work; /* Scalar work */ 54 PetscReal scoeff; /* shift = scoeff/dt */ 55 PetscReal stage_time; 56 PetscBool imex; 57 PetscBool extrapolate; /* Extrapolate initial guess from previous time-step stage values */ 58 TSStepStatus status; 59 } TS_ARKIMEX; 60 /*MC 61 TSARKIMEXARS122 - Second order ARK IMEX scheme. 62 63 This method has one explicit stage and one implicit stage. 64 65 Options Database: 66 . -ts_arkimex_type ars122 67 68 References: 69 . 1. - U. Ascher, S. Ruuth, R. J. Spiteri, Implicit explicit Runge Kutta methods for time dependent Partial Differential Equations. Appl. Numer. Math. 25, (1997). 70 71 Level: advanced 72 73 .seealso: TSARKIMEX, TSARKIMEXType, TSARKIMEXSetType() 74 M*/ 75 /*MC 76 TSARKIMEXA2 - Second order ARK IMEX scheme with A-stable implicit part. 77 78 This method has an explicit stage and one implicit stage, and has an A-stable implicit scheme. This method was provided by Emil Constantinescu. 79 80 Options Database: 81 . -ts_arkimex_type a2 82 83 Level: advanced 84 85 .seealso: TSARKIMEX, TSARKIMEXType, TSARKIMEXSetType() 86 M*/ 87 /*MC 88 TSARKIMEXL2 - Second order ARK IMEX scheme with L-stable implicit part. 89 90 This method has two implicit stages, and L-stable implicit scheme. 91 92 Options Database: 93 . -ts_arkimex_type l2 94 95 References: 96 . 1. - L. Pareschi, G. Russo, Implicit Explicit Runge Kutta schemes and applications to hyperbolic systems with relaxations. Journal of Scientific Computing Volume: 25, Issue: 1, October, 2005. 97 98 Level: advanced 99 100 .seealso: TSARKIMEX, TSARKIMEXType, TSARKIMEXSetType() 101 M*/ 102 /*MC 103 TSARKIMEX1BEE - First order backward Euler represented as an ARK IMEX scheme with extrapolation as error estimator. This is a 3-stage method. 104 105 This method is aimed at starting the integration of implicit DAEs when explicit first-stage ARK methods are used. 106 107 Options Database: 108 . -ts_arkimex_type 1bee 109 110 Level: advanced 111 112 .seealso: TSARKIMEX, TSARKIMEXType, TSARKIMEXSetType() 113 M*/ 114 /*MC 115 TSARKIMEX2C - Second order ARK IMEX scheme with L-stable implicit part. 116 117 This method has one explicit stage and two implicit stages. The implicit part is the same as in TSARKIMEX2D and TSARKIMEX2E, but the explicit part has a larger stability region on the negative real axis. This method was provided by Emil Constantinescu. 118 119 Options Database: 120 . -ts_arkimex_type 2c 121 122 Level: advanced 123 124 .seealso: TSARKIMEX, TSARKIMEXType, TSARKIMEXSetType() 125 M*/ 126 /*MC 127 TSARKIMEX2D - Second order ARK IMEX scheme with L-stable implicit part. 128 129 This method has one explicit stage and two implicit stages. The stability function is independent of the explicit part in the infinity limit of the implict component. This method was provided by Emil Constantinescu. 130 131 Options Database: 132 . -ts_arkimex_type 2d 133 134 Level: advanced 135 136 .seealso: TSARKIMEX, TSARKIMEXType, TSARKIMEXSetType() 137 M*/ 138 /*MC 139 TSARKIMEX2E - Second order ARK IMEX scheme with L-stable implicit part. 140 141 This method has one explicit stage and two implicit stages. It is is an optimal method developed by Emil Constantinescu. 142 143 Options Database: 144 . -ts_arkimex_type 2e 145 146 Level: advanced 147 148 .seealso: TSARKIMEX, TSARKIMEXType, TSARKIMEXSetType() 149 M*/ 150 /*MC 151 TSARKIMEXPRSSP2 - Second order SSP ARK IMEX scheme. 152 153 This method has three implicit stages. 154 155 References: 156 . 1. - L. Pareschi, G. Russo, Implicit Explicit Runge Kutta schemes and applications to hyperbolic systems with relaxations. Journal of Scientific Computing Volume: 25, Issue: 1, October, 2005. 157 158 This method is referred to as SSP2-(3,3,2) in https://arxiv.org/abs/1110.4375 159 160 Options Database: 161 . -ts_arkimex_type prssp2 162 163 Level: advanced 164 165 .seealso: TSARKIMEX, TSARKIMEXType, TSARKIMEXSetType() 166 M*/ 167 /*MC 168 TSARKIMEX3 - Third order ARK IMEX scheme with L-stable implicit part. 169 170 This method has one explicit stage and three implicit stages. 171 172 Options Database: 173 . -ts_arkimex_type 3 174 175 References: 176 . 1. - Kennedy and Carpenter 2003. 177 178 Level: advanced 179 180 .seealso: TSARKIMEX, TSARKIMEXType, TSARKIMEXSetType() 181 M*/ 182 /*MC 183 TSARKIMEXARS443 - Third order ARK IMEX scheme. 184 185 This method has one explicit stage and four implicit stages. 186 187 Options Database: 188 . -ts_arkimex_type ars443 189 190 References: 191 + 1. - U. Ascher, S. Ruuth, R. J. Spiteri, Implicit explicit Runge Kutta methods for time dependent Partial Differential Equations. Appl. Numer. Math. 25, (1997). 192 - 2. - This method is referred to as ARS(4,4,3) in https://arxiv.org/abs/1110.4375 193 194 Level: advanced 195 196 .seealso: TSARKIMEX, TSARKIMEXType, TSARKIMEXSetType() 197 M*/ 198 /*MC 199 TSARKIMEXBPR3 - Third order ARK IMEX scheme. 200 201 This method has one explicit stage and four implicit stages. 202 203 Options Database: 204 . -ts_arkimex_type bpr3 205 206 References: 207 . This method is referred to as ARK3 in https://arxiv.org/abs/1110.4375 208 209 Level: advanced 210 211 .seealso: TSARKIMEX, TSARKIMEXType, TSARKIMEXSetType() 212 M*/ 213 /*MC 214 TSARKIMEX4 - Fourth order ARK IMEX scheme with L-stable implicit part. 215 216 This method has one explicit stage and four implicit stages. 217 218 Options Database: 219 . -ts_arkimex_type 4 220 221 References: 222 . Kennedy and Carpenter 2003. 223 224 Level: advanced 225 226 .seealso: TSARKIMEX, TSARKIMEXType, TSARKIMEXSetType() 227 M*/ 228 /*MC 229 TSARKIMEX5 - Fifth order ARK IMEX scheme with L-stable implicit part. 230 231 This method has one explicit stage and five implicit stages. 232 233 Options Database: 234 . -ts_arkimex_type 5 235 236 References: 237 . Kennedy and Carpenter 2003. 238 239 Level: advanced 240 241 .seealso: TSARKIMEX, TSARKIMEXType, TSARKIMEXSetType() 242 M*/ 243 244 /*@C 245 TSARKIMEXRegisterAll - Registers all of the additive Runge-Kutta implicit-explicit methods in TSARKIMEX 246 247 Not Collective, but should be called by all processes which will need the schemes to be registered 248 249 Level: advanced 250 251 .seealso: TSARKIMEXRegisterDestroy() 252 @*/ 253 PetscErrorCode TSARKIMEXRegisterAll(void) 254 { 255 PetscErrorCode ierr; 256 257 PetscFunctionBegin; 258 if (TSARKIMEXRegisterAllCalled) PetscFunctionReturn(0); 259 TSARKIMEXRegisterAllCalled = PETSC_TRUE; 260 261 { 262 const PetscReal 263 A[3][3] = {{0.0,0.0,0.0}, 264 {0.0,0.0,0.0}, 265 {0.0,0.5,0.0}}, 266 At[3][3] = {{1.0,0.0,0.0}, 267 {0.0,0.5,0.0}, 268 {0.0,0.5,0.5}}, 269 b[3] = {0.0,0.5,0.5}, 270 bembedt[3] = {1.0,0.0,0.0}; 271 ierr = TSARKIMEXRegister(TSARKIMEX1BEE,2,3,&At[0][0],b,NULL,&A[0][0],b,NULL,bembedt,bembedt,1,b,NULL);CHKERRQ(ierr); 272 } 273 { 274 const PetscReal 275 A[2][2] = {{0.0,0.0}, 276 {0.5,0.0}}, 277 At[2][2] = {{0.0,0.0}, 278 {0.0,0.5}}, 279 b[2] = {0.0,1.0}, 280 bembedt[2] = {0.5,0.5}; 281 /* binterpt[2][2] = {{1.0,-1.0},{0.0,1.0}}; second order dense output has poor stability properties and hence it is not currently in use*/ 282 ierr = TSARKIMEXRegister(TSARKIMEXARS122,2,2,&At[0][0],b,NULL,&A[0][0],b,NULL,bembedt,bembedt,1,b,NULL);CHKERRQ(ierr); 283 } 284 { 285 const PetscReal 286 A[2][2] = {{0.0,0.0}, 287 {1.0,0.0}}, 288 At[2][2] = {{0.0,0.0}, 289 {0.5,0.5}}, 290 b[2] = {0.5,0.5}, 291 bembedt[2] = {0.0,1.0}; 292 /* binterpt[2][2] = {{1.0,-0.5},{0.0,0.5}} second order dense output has poor stability properties and hence it is not currently in use*/ 293 ierr = TSARKIMEXRegister(TSARKIMEXA2,2,2,&At[0][0],b,NULL,&A[0][0],b,NULL,bembedt,bembedt,1,b,NULL);CHKERRQ(ierr); 294 } 295 { 296 /* const PetscReal us2 = 1.0-1.0/PetscSqrtReal((PetscReal)2.0); Direct evaluation: 0.2928932188134524755992. Used below to ensure all values are available at compile time */ 297 const PetscReal 298 A[2][2] = {{0.0,0.0}, 299 {1.0,0.0}}, 300 At[2][2] = {{0.2928932188134524755992,0.0}, 301 {1.0-2.0*0.2928932188134524755992,0.2928932188134524755992}}, 302 b[2] = {0.5,0.5}, 303 bembedt[2] = {0.0,1.0}, 304 binterpt[2][2] = {{ (0.2928932188134524755992-1.0)/(2.0*0.2928932188134524755992-1.0),-1/(2.0*(1.0-2.0*0.2928932188134524755992))}, 305 {1-(0.2928932188134524755992-1.0)/(2.0*0.2928932188134524755992-1.0),-1/(2.0*(1.0-2.0*0.2928932188134524755992))}}, 306 binterp[2][2] = {{1.0,-0.5},{0.0,0.5}}; 307 ierr = TSARKIMEXRegister(TSARKIMEXL2,2,2,&At[0][0],b,NULL,&A[0][0],b,NULL,bembedt,bembedt,2,binterpt[0],binterp[0]);CHKERRQ(ierr); 308 } 309 { 310 /* const PetscReal s2 = PetscSqrtReal((PetscReal)2.0), Direct evaluation: 1.414213562373095048802. Used below to ensure all values are available at compile time */ 311 const PetscReal 312 A[3][3] = {{0,0,0}, 313 {2-1.414213562373095048802,0,0}, 314 {0.5,0.5,0}}, 315 At[3][3] = {{0,0,0}, 316 {1-1/1.414213562373095048802,1-1/1.414213562373095048802,0}, 317 {1/(2*1.414213562373095048802),1/(2*1.414213562373095048802),1-1/1.414213562373095048802}}, 318 bembedt[3] = {(4.-1.414213562373095048802)/8.,(4.-1.414213562373095048802)/8.,1/(2.*1.414213562373095048802)}, 319 binterpt[3][2] = {{1.0/1.414213562373095048802,-1.0/(2.0*1.414213562373095048802)}, 320 {1.0/1.414213562373095048802,-1.0/(2.0*1.414213562373095048802)}, 321 {1.0-1.414213562373095048802,1.0/1.414213562373095048802}}; 322 ierr = TSARKIMEXRegister(TSARKIMEX2C,2,3,&At[0][0],NULL,NULL,&A[0][0],NULL,NULL,bembedt,bembedt,2,binterpt[0],NULL);CHKERRQ(ierr); 323 } 324 { 325 /* const PetscReal s2 = PetscSqrtReal((PetscReal)2.0), Direct evaluation: 1.414213562373095048802. Used below to ensure all values are available at compile time */ 326 const PetscReal 327 A[3][3] = {{0,0,0}, 328 {2-1.414213562373095048802,0,0}, 329 {0.75,0.25,0}}, 330 At[3][3] = {{0,0,0}, 331 {1-1/1.414213562373095048802,1-1/1.414213562373095048802,0}, 332 {1/(2*1.414213562373095048802),1/(2*1.414213562373095048802),1-1/1.414213562373095048802}}, 333 bembedt[3] = {(4.-1.414213562373095048802)/8.,(4.-1.414213562373095048802)/8.,1/(2.*1.414213562373095048802)}, 334 binterpt[3][2] = {{1.0/1.414213562373095048802,-1.0/(2.0*1.414213562373095048802)}, 335 {1.0/1.414213562373095048802,-1.0/(2.0*1.414213562373095048802)}, 336 {1.0-1.414213562373095048802,1.0/1.414213562373095048802}}; 337 ierr = TSARKIMEXRegister(TSARKIMEX2D,2,3,&At[0][0],NULL,NULL,&A[0][0],NULL,NULL,bembedt,bembedt,2,binterpt[0],NULL);CHKERRQ(ierr); 338 } 339 { /* Optimal for linear implicit part */ 340 /* const PetscReal s2 = PetscSqrtReal((PetscReal)2.0), Direct evaluation: 1.414213562373095048802. Used below to ensure all values are available at compile time */ 341 const PetscReal 342 A[3][3] = {{0,0,0}, 343 {2-1.414213562373095048802,0,0}, 344 {(3-2*1.414213562373095048802)/6,(3+2*1.414213562373095048802)/6,0}}, 345 At[3][3] = {{0,0,0}, 346 {1-1/1.414213562373095048802,1-1/1.414213562373095048802,0}, 347 {1/(2*1.414213562373095048802),1/(2*1.414213562373095048802),1-1/1.414213562373095048802}}, 348 bembedt[3] = {(4.-1.414213562373095048802)/8.,(4.-1.414213562373095048802)/8.,1/(2.*1.414213562373095048802)}, 349 binterpt[3][2] = {{1.0/1.414213562373095048802,-1.0/(2.0*1.414213562373095048802)}, 350 {1.0/1.414213562373095048802,-1.0/(2.0*1.414213562373095048802)}, 351 {1.0-1.414213562373095048802,1.0/1.414213562373095048802}}; 352 ierr = TSARKIMEXRegister(TSARKIMEX2E,2,3,&At[0][0],NULL,NULL,&A[0][0],NULL,NULL,bembedt,bembedt,2,binterpt[0],NULL);CHKERRQ(ierr); 353 } 354 { /* Optimal for linear implicit part */ 355 const PetscReal 356 A[3][3] = {{0,0,0}, 357 {0.5,0,0}, 358 {0.5,0.5,0}}, 359 At[3][3] = {{0.25,0,0}, 360 {0,0.25,0}, 361 {1./3,1./3,1./3}}; 362 ierr = TSARKIMEXRegister(TSARKIMEXPRSSP2,2,3,&At[0][0],NULL,NULL,&A[0][0],NULL,NULL,NULL,NULL,0,NULL,NULL);CHKERRQ(ierr); 363 } 364 { 365 const PetscReal 366 A[4][4] = {{0,0,0,0}, 367 {1767732205903./2027836641118.,0,0,0}, 368 {5535828885825./10492691773637.,788022342437./10882634858940.,0,0}, 369 {6485989280629./16251701735622.,-4246266847089./9704473918619.,10755448449292./10357097424841.,0}}, 370 At[4][4] = {{0,0,0,0}, 371 {1767732205903./4055673282236.,1767732205903./4055673282236.,0,0}, 372 {2746238789719./10658868560708.,-640167445237./6845629431997.,1767732205903./4055673282236.,0}, 373 {1471266399579./7840856788654.,-4482444167858./7529755066697.,11266239266428./11593286722821.,1767732205903./4055673282236.}}, 374 bembedt[4] = {2756255671327./12835298489170.,-10771552573575./22201958757719.,9247589265047./10645013368117.,2193209047091./5459859503100.}, 375 binterpt[4][2] = {{4655552711362./22874653954995., -215264564351./13552729205753.}, 376 {-18682724506714./9892148508045.,17870216137069./13817060693119.}, 377 {34259539580243./13192909600954.,-28141676662227./17317692491321.}, 378 {584795268549./6622622206610., 2508943948391./7218656332882.}}; 379 ierr = TSARKIMEXRegister(TSARKIMEX3,3,4,&At[0][0],NULL,NULL,&A[0][0],NULL,NULL,bembedt,bembedt,2,binterpt[0],NULL);CHKERRQ(ierr); 380 } 381 { 382 const PetscReal 383 A[5][5] = {{0,0,0,0,0}, 384 {1./2,0,0,0,0}, 385 {11./18,1./18,0,0,0}, 386 {5./6,-5./6,.5,0,0}, 387 {1./4,7./4,3./4,-7./4,0}}, 388 At[5][5] = {{0,0,0,0,0}, 389 {0,1./2,0,0,0}, 390 {0,1./6,1./2,0,0}, 391 {0,-1./2,1./2,1./2,0}, 392 {0,3./2,-3./2,1./2,1./2}}, 393 *bembedt = NULL; 394 ierr = TSARKIMEXRegister(TSARKIMEXARS443,3,5,&At[0][0],NULL,NULL,&A[0][0],NULL,NULL,bembedt,bembedt,0,NULL,NULL);CHKERRQ(ierr); 395 } 396 { 397 const PetscReal 398 A[5][5] = {{0,0,0,0,0}, 399 {1,0,0,0,0}, 400 {4./9,2./9,0,0,0}, 401 {1./4,0,3./4,0,0}, 402 {1./4,0,3./5,0,0}}, 403 At[5][5] = {{0,0,0,0,0}, 404 {.5,.5,0,0,0}, 405 {5./18,-1./9,.5,0,0}, 406 {.5,0,0,.5,0}, 407 {.25,0,.75,-.5,.5}}, 408 *bembedt = NULL; 409 ierr = TSARKIMEXRegister(TSARKIMEXBPR3,3,5,&At[0][0],NULL,NULL,&A[0][0],NULL,NULL,bembedt,bembedt,0,NULL,NULL);CHKERRQ(ierr); 410 } 411 { 412 const PetscReal 413 A[6][6] = {{0,0,0,0,0,0}, 414 {1./2,0,0,0,0,0}, 415 {13861./62500.,6889./62500.,0,0,0,0}, 416 {-116923316275./2393684061468.,-2731218467317./15368042101831.,9408046702089./11113171139209.,0,0,0}, 417 {-451086348788./2902428689909.,-2682348792572./7519795681897.,12662868775082./11960479115383.,3355817975965./11060851509271.,0,0}, 418 {647845179188./3216320057751.,73281519250./8382639484533.,552539513391./3454668386233.,3354512671639./8306763924573.,4040./17871.,0}}, 419 At[6][6] = {{0,0,0,0,0,0}, 420 {1./4,1./4,0,0,0,0}, 421 {8611./62500.,-1743./31250.,1./4,0,0,0}, 422 {5012029./34652500.,-654441./2922500.,174375./388108.,1./4,0,0}, 423 {15267082809./155376265600.,-71443401./120774400.,730878875./902184768.,2285395./8070912.,1./4,0}, 424 {82889./524892.,0,15625./83664.,69875./102672.,-2260./8211,1./4}}, 425 bembedt[6] = {4586570599./29645900160.,0,178811875./945068544.,814220225./1159782912.,-3700637./11593932.,61727./225920.}, 426 binterpt[6][3] = {{6943876665148./7220017795957.,-54480133./30881146.,6818779379841./7100303317025.}, 427 {0,0,0}, 428 {7640104374378./9702883013639.,-11436875./14766696.,2173542590792./12501825683035.}, 429 {-20649996744609./7521556579894.,174696575./18121608.,-31592104683404./5083833661969.}, 430 {8854892464581./2390941311638.,-12120380./966161.,61146701046299./7138195549469.}, 431 {-11397109935349./6675773540249.,3843./706.,-17219254887155./4939391667607.}}; 432 ierr = TSARKIMEXRegister(TSARKIMEX4,4,6,&At[0][0],NULL,NULL,&A[0][0],NULL,NULL,bembedt,bembedt,3,binterpt[0],NULL);CHKERRQ(ierr); 433 } 434 { 435 const PetscReal 436 A[8][8] = {{0,0,0,0,0,0,0,0}, 437 {41./100,0,0,0,0,0,0,0}, 438 {367902744464./2072280473677.,677623207551./8224143866563.,0,0,0,0,0,0}, 439 {1268023523408./10340822734521.,0,1029933939417./13636558850479.,0,0,0,0,0}, 440 {14463281900351./6315353703477.,0,66114435211212./5879490589093.,-54053170152839./4284798021562.,0,0,0,0}, 441 {14090043504691./34967701212078.,0,15191511035443./11219624916014.,-18461159152457./12425892160975.,-281667163811./9011619295870.,0,0,0}, 442 {19230459214898./13134317526959.,0,21275331358303./2942455364971.,-38145345988419./4862620318723.,-1./8,-1./8,0,0}, 443 {-19977161125411./11928030595625.,0,-40795976796054./6384907823539.,177454434618887./12078138498510.,782672205425./8267701900261.,-69563011059811./9646580694205.,7356628210526./4942186776405.,0}}, 444 At[8][8] = {{0,0,0,0,0,0,0,0}, 445 {41./200.,41./200.,0,0,0,0,0,0}, 446 {41./400.,-567603406766./11931857230679.,41./200.,0,0,0,0,0}, 447 {683785636431./9252920307686.,0,-110385047103./1367015193373.,41./200.,0,0,0,0}, 448 {3016520224154./10081342136671.,0,30586259806659./12414158314087.,-22760509404356./11113319521817.,41./200.,0,0,0}, 449 {218866479029./1489978393911.,0,638256894668./5436446318841.,-1179710474555./5321154724896.,-60928119172./8023461067671.,41./200.,0,0}, 450 {1020004230633./5715676835656.,0,25762820946817./25263940353407.,-2161375909145./9755907335909.,-211217309593./5846859502534.,-4269925059573./7827059040749.,41./200,0}, 451 {-872700587467./9133579230613.,0,0,22348218063261./9555858737531.,-1143369518992./8141816002931.,-39379526789629./19018526304540.,32727382324388./42900044865799.,41./200.}}, 452 bembedt[8] = {-975461918565./9796059967033.,0,0,78070527104295./32432590147079.,-548382580838./3424219808633.,-33438840321285./15594753105479.,3629800801594./4656183773603.,4035322873751./18575991585200.}, 453 binterpt[8][3] = {{-17674230611817./10670229744614., 43486358583215./12773830924787., -9257016797708./5021505065439.}, 454 {0, 0, 0 }, 455 {0, 0, 0 }, 456 {65168852399939./7868540260826., -91478233927265./11067650958493., 26096422576131./11239449250142.}, 457 {15494834004392./5936557850923., -79368583304911./10890268929626., 92396832856987./20362823103730.}, 458 {-99329723586156./26959484932159., -12239297817655./9152339842473., 30029262896817./10175596800299.}, 459 {-19024464361622./5461577185407., 115839755401235./10719374521269., -26136350496073./3983972220547.}, 460 {-6511271360970./6095937251113., 5843115559534./2180450260947., -5289405421727./3760307252460. }}; 461 ierr = TSARKIMEXRegister(TSARKIMEX5,5,8,&At[0][0],NULL,NULL,&A[0][0],NULL,NULL,bembedt,bembedt,3,binterpt[0],NULL);CHKERRQ(ierr); 462 } 463 PetscFunctionReturn(0); 464 } 465 466 /*@C 467 TSARKIMEXRegisterDestroy - Frees the list of schemes that were registered by TSARKIMEXRegister(). 468 469 Not Collective 470 471 Level: advanced 472 473 .seealso: TSARKIMEXRegister(), TSARKIMEXRegisterAll() 474 @*/ 475 PetscErrorCode TSARKIMEXRegisterDestroy(void) 476 { 477 PetscErrorCode ierr; 478 ARKTableauLink link; 479 480 PetscFunctionBegin; 481 while ((link = ARKTableauList)) { 482 ARKTableau t = &link->tab; 483 ARKTableauList = link->next; 484 ierr = PetscFree6(t->At,t->bt,t->ct,t->A,t->b,t->c);CHKERRQ(ierr); 485 ierr = PetscFree2(t->bembedt,t->bembed);CHKERRQ(ierr); 486 ierr = PetscFree2(t->binterpt,t->binterp);CHKERRQ(ierr); 487 ierr = PetscFree(t->name);CHKERRQ(ierr); 488 ierr = PetscFree(link);CHKERRQ(ierr); 489 } 490 TSARKIMEXRegisterAllCalled = PETSC_FALSE; 491 PetscFunctionReturn(0); 492 } 493 494 /*@C 495 TSARKIMEXInitializePackage - This function initializes everything in the TSARKIMEX package. It is called 496 from TSInitializePackage(). 497 498 Level: developer 499 500 .seealso: PetscInitialize() 501 @*/ 502 PetscErrorCode TSARKIMEXInitializePackage(void) 503 { 504 PetscErrorCode ierr; 505 506 PetscFunctionBegin; 507 if (TSARKIMEXPackageInitialized) PetscFunctionReturn(0); 508 TSARKIMEXPackageInitialized = PETSC_TRUE; 509 ierr = TSARKIMEXRegisterAll();CHKERRQ(ierr); 510 ierr = PetscRegisterFinalize(TSARKIMEXFinalizePackage);CHKERRQ(ierr); 511 PetscFunctionReturn(0); 512 } 513 514 /*@C 515 TSARKIMEXFinalizePackage - This function destroys everything in the TSARKIMEX package. It is 516 called from PetscFinalize(). 517 518 Level: developer 519 520 .seealso: PetscFinalize() 521 @*/ 522 PetscErrorCode TSARKIMEXFinalizePackage(void) 523 { 524 PetscErrorCode ierr; 525 526 PetscFunctionBegin; 527 TSARKIMEXPackageInitialized = PETSC_FALSE; 528 ierr = TSARKIMEXRegisterDestroy();CHKERRQ(ierr); 529 PetscFunctionReturn(0); 530 } 531 532 /*@C 533 TSARKIMEXRegister - register an ARK IMEX scheme by providing the entries in the Butcher tableau and optionally embedded approximations and interpolation 534 535 Not Collective, but the same schemes should be registered on all processes on which they will be used 536 537 Input Parameters: 538 + name - identifier for method 539 . order - approximation order of method 540 . s - number of stages, this is the dimension of the matrices below 541 . At - Butcher table of stage coefficients for stiff part (dimension s*s, row-major) 542 . bt - Butcher table for completing the stiff part of the step (dimension s; NULL to use the last row of At) 543 . ct - Abscissa of each stiff stage (dimension s, NULL to use row sums of At) 544 . A - Non-stiff stage coefficients (dimension s*s, row-major) 545 . b - Non-stiff step completion table (dimension s; NULL to use last row of At) 546 . c - Non-stiff abscissa (dimension s; NULL to use row sums of A) 547 . bembedt - Stiff part of completion table for embedded method (dimension s; NULL if not available) 548 . bembed - Non-stiff part of completion table for embedded method (dimension s; NULL to use bembedt if provided) 549 . pinterp - Order of the interpolation scheme, equal to the number of columns of binterpt and binterp 550 . binterpt - Coefficients of the interpolation formula for the stiff part (dimension s*pinterp) 551 - binterp - Coefficients of the interpolation formula for the non-stiff part (dimension s*pinterp; NULL to reuse binterpt) 552 553 Notes: 554 Several ARK IMEX methods are provided, this function is only needed to create new methods. 555 556 Level: advanced 557 558 .seealso: TSARKIMEX 559 @*/ 560 PetscErrorCode TSARKIMEXRegister(TSARKIMEXType name,PetscInt order,PetscInt s, 561 const PetscReal At[],const PetscReal bt[],const PetscReal ct[], 562 const PetscReal A[],const PetscReal b[],const PetscReal c[], 563 const PetscReal bembedt[],const PetscReal bembed[], 564 PetscInt pinterp,const PetscReal binterpt[],const PetscReal binterp[]) 565 { 566 PetscErrorCode ierr; 567 ARKTableauLink link; 568 ARKTableau t; 569 PetscInt i,j; 570 571 PetscFunctionBegin; 572 ierr = TSARKIMEXInitializePackage();CHKERRQ(ierr); 573 ierr = PetscNew(&link);CHKERRQ(ierr); 574 t = &link->tab; 575 ierr = PetscStrallocpy(name,&t->name);CHKERRQ(ierr); 576 t->order = order; 577 t->s = s; 578 ierr = PetscMalloc6(s*s,&t->At,s,&t->bt,s,&t->ct,s*s,&t->A,s,&t->b,s,&t->c);CHKERRQ(ierr); 579 ierr = PetscArraycpy(t->At,At,s*s);CHKERRQ(ierr); 580 ierr = PetscArraycpy(t->A,A,s*s);CHKERRQ(ierr); 581 if (bt) { ierr = PetscArraycpy(t->bt,bt,s);CHKERRQ(ierr); } 582 else for (i=0; i<s; i++) t->bt[i] = At[(s-1)*s+i]; 583 if (b) { ierr = PetscArraycpy(t->b,b,s);CHKERRQ(ierr); } 584 else for (i=0; i<s; i++) t->b[i] = t->bt[i]; 585 if (ct) { ierr = PetscArraycpy(t->ct,ct,s);CHKERRQ(ierr); } 586 else for (i=0; i<s; i++) for (j=0,t->ct[i]=0; j<s; j++) t->ct[i] += At[i*s+j]; 587 if (c) { ierr = PetscArraycpy(t->c,c,s);CHKERRQ(ierr); } 588 else for (i=0; i<s; i++) for (j=0,t->c[i]=0; j<s; j++) t->c[i] += A[i*s+j]; 589 t->stiffly_accurate = PETSC_TRUE; 590 for (i=0; i<s; i++) if (t->At[(s-1)*s+i] != t->bt[i]) t->stiffly_accurate = PETSC_FALSE; 591 t->explicit_first_stage = PETSC_TRUE; 592 for (i=0; i<s; i++) if (t->At[i] != 0.0) t->explicit_first_stage = PETSC_FALSE; 593 /*def of FSAL can be made more precise*/ 594 t->FSAL_implicit = (PetscBool)(t->explicit_first_stage && t->stiffly_accurate); 595 if (bembedt) { 596 ierr = PetscMalloc2(s,&t->bembedt,s,&t->bembed);CHKERRQ(ierr); 597 ierr = PetscArraycpy(t->bembedt,bembedt,s);CHKERRQ(ierr); 598 ierr = PetscArraycpy(t->bembed,bembed ? bembed : bembedt,s);CHKERRQ(ierr); 599 } 600 601 t->pinterp = pinterp; 602 ierr = PetscMalloc2(s*pinterp,&t->binterpt,s*pinterp,&t->binterp);CHKERRQ(ierr); 603 ierr = PetscArraycpy(t->binterpt,binterpt,s*pinterp);CHKERRQ(ierr); 604 ierr = PetscArraycpy(t->binterp,binterp ? binterp : binterpt,s*pinterp);CHKERRQ(ierr); 605 link->next = ARKTableauList; 606 ARKTableauList = link; 607 PetscFunctionReturn(0); 608 } 609 610 /* 611 The step completion formula is 612 613 x1 = x0 - h bt^T YdotI + h b^T YdotRHS 614 615 This function can be called before or after ts->vec_sol has been updated. 616 Suppose we have a completion formula (bt,b) and an embedded formula (bet,be) of different order. 617 We can write 618 619 x1e = x0 - h bet^T YdotI + h be^T YdotRHS 620 = x1 + h bt^T YdotI - h b^T YdotRHS - h bet^T YdotI + h be^T YdotRHS 621 = x1 - h (bet - bt)^T YdotI + h (be - b)^T YdotRHS 622 623 so we can evaluate the method with different order even after the step has been optimistically completed. 624 */ 625 static PetscErrorCode TSEvaluateStep_ARKIMEX(TS ts,PetscInt order,Vec X,PetscBool *done) 626 { 627 TS_ARKIMEX *ark = (TS_ARKIMEX*)ts->data; 628 ARKTableau tab = ark->tableau; 629 PetscScalar *w = ark->work; 630 PetscReal h; 631 PetscInt s = tab->s,j; 632 PetscErrorCode ierr; 633 634 PetscFunctionBegin; 635 switch (ark->status) { 636 case TS_STEP_INCOMPLETE: 637 case TS_STEP_PENDING: 638 h = ts->time_step; break; 639 case TS_STEP_COMPLETE: 640 h = ts->ptime - ts->ptime_prev; break; 641 default: SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_PLIB,"Invalid TSStepStatus"); 642 } 643 if (order == tab->order) { 644 if (ark->status == TS_STEP_INCOMPLETE) { 645 if (!ark->imex && tab->stiffly_accurate) { /* Only the stiffly accurate implicit formula is used */ 646 ierr = VecCopy(ark->Y[s-1],X);CHKERRQ(ierr); 647 } else { /* Use the standard completion formula (bt,b) */ 648 ierr = VecCopy(ts->vec_sol,X);CHKERRQ(ierr); 649 for (j=0; j<s; j++) w[j] = h*tab->bt[j]; 650 ierr = VecMAXPY(X,s,w,ark->YdotI);CHKERRQ(ierr); 651 if (ark->imex) { /* Method is IMEX, complete the explicit formula */ 652 for (j=0; j<s; j++) w[j] = h*tab->b[j]; 653 ierr = VecMAXPY(X,s,w,ark->YdotRHS);CHKERRQ(ierr); 654 } 655 } 656 } else {ierr = VecCopy(ts->vec_sol,X);CHKERRQ(ierr);} 657 if (done) *done = PETSC_TRUE; 658 PetscFunctionReturn(0); 659 } else if (order == tab->order-1) { 660 if (!tab->bembedt) goto unavailable; 661 if (ark->status == TS_STEP_INCOMPLETE) { /* Complete with the embedded method (bet,be) */ 662 ierr = VecCopy(ts->vec_sol,X);CHKERRQ(ierr); 663 for (j=0; j<s; j++) w[j] = h*tab->bembedt[j]; 664 ierr = VecMAXPY(X,s,w,ark->YdotI);CHKERRQ(ierr); 665 for (j=0; j<s; j++) w[j] = h*tab->bembed[j]; 666 ierr = VecMAXPY(X,s,w,ark->YdotRHS);CHKERRQ(ierr); 667 } else { /* Rollback and re-complete using (bet-be,be-b) */ 668 ierr = VecCopy(ts->vec_sol,X);CHKERRQ(ierr); 669 for (j=0; j<s; j++) w[j] = h*(tab->bembedt[j] - tab->bt[j]); 670 ierr = VecMAXPY(X,tab->s,w,ark->YdotI);CHKERRQ(ierr); 671 for (j=0; j<s; j++) w[j] = h*(tab->bembed[j] - tab->b[j]); 672 ierr = VecMAXPY(X,s,w,ark->YdotRHS);CHKERRQ(ierr); 673 } 674 if (done) *done = PETSC_TRUE; 675 PetscFunctionReturn(0); 676 } 677 unavailable: 678 if (done) *done = PETSC_FALSE; 679 else SETERRQ3(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"ARKIMEX '%s' of order %D cannot evaluate step at order %D. Consider using -ts_adapt_type none or a different method that has an embedded estimate.",tab->name,tab->order,order); 680 PetscFunctionReturn(0); 681 } 682 683 static PetscErrorCode TSARKIMEXTestMassIdentity(TS ts,PetscBool *id) 684 { 685 PetscErrorCode ierr; 686 Vec Udot,Y1,Y2; 687 TS_ARKIMEX *ark = (TS_ARKIMEX*)ts->data; 688 PetscReal norm; 689 690 PetscFunctionBegin; 691 ierr = VecDuplicate(ts->vec_sol,&Udot);CHKERRQ(ierr); 692 ierr = VecDuplicate(ts->vec_sol,&Y1);CHKERRQ(ierr); 693 ierr = VecDuplicate(ts->vec_sol,&Y2);CHKERRQ(ierr); 694 ierr = TSComputeIFunction(ts,ts->ptime,ts->vec_sol,Udot,Y1,ark->imex);CHKERRQ(ierr); 695 ierr = VecSetRandom(Udot,NULL);CHKERRQ(ierr); 696 ierr = TSComputeIFunction(ts,ts->ptime,ts->vec_sol,Udot,Y2,ark->imex);CHKERRQ(ierr); 697 ierr = VecAXPY(Y2,-1.0,Y1);CHKERRQ(ierr); 698 ierr = VecAXPY(Y2,-1.0,Udot);CHKERRQ(ierr); 699 ierr = VecNorm(Y2,NORM_2,&norm);CHKERRQ(ierr); 700 if (norm < 100.0*PETSC_MACHINE_EPSILON) { 701 *id = PETSC_TRUE; 702 } else { 703 *id = PETSC_FALSE; 704 ierr = PetscInfo1((PetscObject)ts,"IFunction(Udot = random) - IFunction(Udot = 0) is not near Udot, %g, suspect mass matrix implied in IFunction() is not the identity as required\n",(double)norm);CHKERRQ(ierr); 705 } 706 ierr = VecDestroy(&Udot);CHKERRQ(ierr); 707 ierr = VecDestroy(&Y1);CHKERRQ(ierr); 708 ierr = VecDestroy(&Y2);CHKERRQ(ierr); 709 PetscFunctionReturn(0); 710 } 711 712 static PetscErrorCode TSRollBack_ARKIMEX(TS ts) 713 { 714 TS_ARKIMEX *ark = (TS_ARKIMEX*)ts->data; 715 ARKTableau tab = ark->tableau; 716 const PetscInt s = tab->s; 717 const PetscReal *bt = tab->bt,*b = tab->b; 718 PetscScalar *w = ark->work; 719 Vec *YdotI = ark->YdotI,*YdotRHS = ark->YdotRHS; 720 PetscInt j; 721 PetscReal h; 722 PetscErrorCode ierr; 723 724 PetscFunctionBegin; 725 switch (ark->status) { 726 case TS_STEP_INCOMPLETE: 727 case TS_STEP_PENDING: 728 h = ts->time_step; break; 729 case TS_STEP_COMPLETE: 730 h = ts->ptime - ts->ptime_prev; break; 731 default: SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_PLIB,"Invalid TSStepStatus"); 732 } 733 for (j=0; j<s; j++) w[j] = -h*bt[j]; 734 ierr = VecMAXPY(ts->vec_sol,s,w,YdotI);CHKERRQ(ierr); 735 for (j=0; j<s; j++) w[j] = -h*b[j]; 736 ierr = VecMAXPY(ts->vec_sol,s,w,YdotRHS);CHKERRQ(ierr); 737 PetscFunctionReturn(0); 738 } 739 740 static PetscErrorCode TSStep_ARKIMEX(TS ts) 741 { 742 TS_ARKIMEX *ark = (TS_ARKIMEX*)ts->data; 743 ARKTableau tab = ark->tableau; 744 const PetscInt s = tab->s; 745 const PetscReal *At = tab->At,*A = tab->A,*ct = tab->ct,*c = tab->c; 746 PetscScalar *w = ark->work; 747 Vec *Y = ark->Y,*YdotI = ark->YdotI,*YdotRHS = ark->YdotRHS,Ydot = ark->Ydot,Ydot0 = ark->Ydot0,Z = ark->Z; 748 PetscBool extrapolate = ark->extrapolate; 749 TSAdapt adapt; 750 SNES snes; 751 PetscInt i,j,its,lits; 752 PetscInt rejections = 0; 753 PetscBool stageok,accept = PETSC_TRUE; 754 PetscReal next_time_step = ts->time_step; 755 PetscErrorCode ierr; 756 757 PetscFunctionBegin; 758 if (ark->extrapolate && !ark->Y_prev) { 759 ierr = VecDuplicateVecs(ts->vec_sol,tab->s,&ark->Y_prev);CHKERRQ(ierr); 760 ierr = VecDuplicateVecs(ts->vec_sol,tab->s,&ark->YdotI_prev);CHKERRQ(ierr); 761 ierr = VecDuplicateVecs(ts->vec_sol,tab->s,&ark->YdotRHS_prev);CHKERRQ(ierr); 762 } 763 764 if (!ts->steprollback) { 765 if (ts->equation_type >= TS_EQ_IMPLICIT) { /* Save the initial slope for the next step */ 766 ierr = VecCopy(YdotI[s-1],Ydot0);CHKERRQ(ierr); 767 } 768 if (ark->extrapolate && !ts->steprestart) { /* Save the Y, YdotI, YdotRHS for extrapolation initial guess */ 769 for (i = 0; i<s; i++) { 770 ierr = VecCopy(Y[i],ark->Y_prev[i]);CHKERRQ(ierr); 771 ierr = VecCopy(YdotRHS[i],ark->YdotRHS_prev[i]);CHKERRQ(ierr); 772 ierr = VecCopy(YdotI[i],ark->YdotI_prev[i]);CHKERRQ(ierr); 773 } 774 } 775 } 776 777 if (ts->equation_type >= TS_EQ_IMPLICIT && tab->explicit_first_stage && ts->steprestart) { 778 TS ts_start; 779 if (PetscDefined(USE_DEBUG)) { 780 PetscBool id = PETSC_FALSE; 781 ierr = TSARKIMEXTestMassIdentity(ts,&id);CHKERRQ(ierr); 782 if (!id) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_INCOMP,"This scheme requires an identity mass matrix, however the TSIFunction you provide does not utilize an identity mass matrix"); 783 } 784 ierr = TSClone(ts,&ts_start);CHKERRQ(ierr); 785 ierr = TSSetSolution(ts_start,ts->vec_sol);CHKERRQ(ierr); 786 ierr = TSSetTime(ts_start,ts->ptime);CHKERRQ(ierr); 787 ierr = TSSetMaxSteps(ts_start,ts->steps+1);CHKERRQ(ierr); 788 ierr = TSSetMaxTime(ts_start,ts->ptime+ts->time_step);CHKERRQ(ierr); 789 ierr = TSSetExactFinalTime(ts_start,TS_EXACTFINALTIME_STEPOVER);CHKERRQ(ierr); 790 ierr = TSSetTimeStep(ts_start,ts->time_step);CHKERRQ(ierr); 791 ierr = TSSetType(ts_start,TSARKIMEX);CHKERRQ(ierr); 792 ierr = TSARKIMEXSetFullyImplicit(ts_start,PETSC_TRUE);CHKERRQ(ierr); 793 ierr = TSARKIMEXSetType(ts_start,TSARKIMEX1BEE);CHKERRQ(ierr); 794 795 ierr = TSRestartStep(ts_start);CHKERRQ(ierr); 796 ierr = TSSolve(ts_start,ts->vec_sol);CHKERRQ(ierr); 797 ierr = TSGetTime(ts_start,&ts->ptime);CHKERRQ(ierr); 798 ierr = TSGetTimeStep(ts_start,&ts->time_step);CHKERRQ(ierr); 799 800 { /* Save the initial slope for the next step */ 801 TS_ARKIMEX *ark_start = (TS_ARKIMEX*)ts_start->data; 802 ierr = VecCopy(ark_start->YdotI[ark_start->tableau->s-1],Ydot0);CHKERRQ(ierr); 803 } 804 ts->steps++; 805 806 /* Set the correct TS in SNES */ 807 /* We'll try to bypass this by changing the method on the fly */ 808 { 809 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 810 ierr = TSSetSNES(ts,snes);CHKERRQ(ierr); 811 } 812 ierr = TSDestroy(&ts_start);CHKERRQ(ierr); 813 } 814 815 ark->status = TS_STEP_INCOMPLETE; 816 while (!ts->reason && ark->status != TS_STEP_COMPLETE) { 817 PetscReal t = ts->ptime; 818 PetscReal h = ts->time_step; 819 for (i=0; i<s; i++) { 820 ark->stage_time = t + h*ct[i]; 821 ierr = TSPreStage(ts,ark->stage_time);CHKERRQ(ierr); 822 if (At[i*s+i] == 0) { /* This stage is explicit */ 823 if (i!=0 && ts->equation_type >= TS_EQ_IMPLICIT) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Explicit stages other than the first one are not supported for implicit problems"); 824 ierr = VecCopy(ts->vec_sol,Y[i]);CHKERRQ(ierr); 825 for (j=0; j<i; j++) w[j] = h*At[i*s+j]; 826 ierr = VecMAXPY(Y[i],i,w,YdotI);CHKERRQ(ierr); 827 for (j=0; j<i; j++) w[j] = h*A[i*s+j]; 828 ierr = VecMAXPY(Y[i],i,w,YdotRHS);CHKERRQ(ierr); 829 } else { 830 ark->scoeff = 1./At[i*s+i]; 831 /* Ydot = shift*(Y-Z) */ 832 ierr = VecCopy(ts->vec_sol,Z);CHKERRQ(ierr); 833 for (j=0; j<i; j++) w[j] = h*At[i*s+j]; 834 ierr = VecMAXPY(Z,i,w,YdotI);CHKERRQ(ierr); 835 for (j=0; j<i; j++) w[j] = h*A[i*s+j]; 836 ierr = VecMAXPY(Z,i,w,YdotRHS);CHKERRQ(ierr); 837 if (extrapolate && !ts->steprestart) { 838 /* Initial guess extrapolated from previous time step stage values */ 839 ierr = TSExtrapolate_ARKIMEX(ts,c[i],Y[i]);CHKERRQ(ierr); 840 } else { 841 /* Initial guess taken from last stage */ 842 ierr = VecCopy(i>0 ? Y[i-1] : ts->vec_sol,Y[i]);CHKERRQ(ierr); 843 } 844 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 845 ierr = SNESSolve(snes,NULL,Y[i]);CHKERRQ(ierr); 846 ierr = SNESGetIterationNumber(snes,&its);CHKERRQ(ierr); 847 ierr = SNESGetLinearSolveIterations(snes,&lits);CHKERRQ(ierr); 848 ts->snes_its += its; ts->ksp_its += lits; 849 ierr = TSGetAdapt(ts,&adapt);CHKERRQ(ierr); 850 ierr = TSAdaptCheckStage(adapt,ts,ark->stage_time,Y[i],&stageok);CHKERRQ(ierr); 851 if (!stageok) { 852 /* We are likely rejecting the step because of solver or function domain problems so we should not attempt to 853 * use extrapolation to initialize the solves on the next attempt. */ 854 extrapolate = PETSC_FALSE; 855 goto reject_step; 856 } 857 } 858 if (ts->equation_type >= TS_EQ_IMPLICIT) { 859 if (i==0 && tab->explicit_first_stage) { 860 if (!tab->stiffly_accurate) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSARKIMEX %s is not stiffly accurate and therefore explicit-first stage methods cannot be used if the equation is implicit because the slope cannot be evaluated",ark->tableau->name); 861 ierr = VecCopy(Ydot0,YdotI[0]);CHKERRQ(ierr); /* YdotI = YdotI(tn-1) */ 862 } else { 863 ierr = VecAXPBYPCZ(YdotI[i],-ark->scoeff/h,ark->scoeff/h,0,Z,Y[i]);CHKERRQ(ierr); /* YdotI = shift*(X-Z) */ 864 } 865 } else { 866 if (i==0 && tab->explicit_first_stage) { 867 ierr = VecZeroEntries(Ydot);CHKERRQ(ierr); 868 ierr = TSComputeIFunction(ts,t+h*ct[i],Y[i],Ydot,YdotI[i],ark->imex);CHKERRQ(ierr);/* YdotI = -G(t,Y,0) */ 869 ierr = VecScale(YdotI[i],-1.0);CHKERRQ(ierr); 870 } else { 871 ierr = VecAXPBYPCZ(YdotI[i],-ark->scoeff/h,ark->scoeff/h,0,Z,Y[i]);CHKERRQ(ierr); /* YdotI = shift*(X-Z) */ 872 } 873 if (ark->imex) { 874 ierr = TSComputeRHSFunction(ts,t+h*c[i],Y[i],YdotRHS[i]);CHKERRQ(ierr); 875 } else { 876 ierr = VecZeroEntries(YdotRHS[i]);CHKERRQ(ierr); 877 } 878 } 879 ierr = TSPostStage(ts,ark->stage_time,i,Y);CHKERRQ(ierr); 880 } 881 882 ark->status = TS_STEP_INCOMPLETE; 883 ierr = TSEvaluateStep_ARKIMEX(ts,tab->order,ts->vec_sol,NULL);CHKERRQ(ierr); 884 ark->status = TS_STEP_PENDING; 885 ierr = TSGetAdapt(ts,&adapt);CHKERRQ(ierr); 886 ierr = TSAdaptCandidatesClear(adapt);CHKERRQ(ierr); 887 ierr = TSAdaptCandidateAdd(adapt,tab->name,tab->order,1,tab->ccfl,(PetscReal)tab->s,PETSC_TRUE);CHKERRQ(ierr); 888 ierr = TSAdaptChoose(adapt,ts,ts->time_step,NULL,&next_time_step,&accept);CHKERRQ(ierr); 889 ark->status = accept ? TS_STEP_COMPLETE : TS_STEP_INCOMPLETE; 890 if (!accept) { /* Roll back the current step */ 891 ierr = TSRollBack_ARKIMEX(ts);CHKERRQ(ierr); 892 ts->time_step = next_time_step; 893 goto reject_step; 894 } 895 896 ts->ptime += ts->time_step; 897 ts->time_step = next_time_step; 898 break; 899 900 reject_step: 901 ts->reject++; accept = PETSC_FALSE; 902 if (!ts->reason && ++rejections > ts->max_reject && ts->max_reject >= 0) { 903 ts->reason = TS_DIVERGED_STEP_REJECTED; 904 ierr = PetscInfo2(ts,"Step=%D, step rejections %D greater than current TS allowed, stopping solve\n",ts->steps,rejections);CHKERRQ(ierr); 905 } 906 } 907 PetscFunctionReturn(0); 908 } 909 910 static PetscErrorCode TSInterpolate_ARKIMEX(TS ts,PetscReal itime,Vec X) 911 { 912 TS_ARKIMEX *ark = (TS_ARKIMEX*)ts->data; 913 PetscInt s = ark->tableau->s,pinterp = ark->tableau->pinterp,i,j; 914 PetscReal h; 915 PetscReal tt,t; 916 PetscScalar *bt,*b; 917 const PetscReal *Bt = ark->tableau->binterpt,*B = ark->tableau->binterp; 918 PetscErrorCode ierr; 919 920 PetscFunctionBegin; 921 if (!Bt || !B) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSARKIMEX %s does not have an interpolation formula",ark->tableau->name); 922 switch (ark->status) { 923 case TS_STEP_INCOMPLETE: 924 case TS_STEP_PENDING: 925 h = ts->time_step; 926 t = (itime - ts->ptime)/h; 927 break; 928 case TS_STEP_COMPLETE: 929 h = ts->ptime - ts->ptime_prev; 930 t = (itime - ts->ptime)/h + 1; /* In the interval [0,1] */ 931 break; 932 default: SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_PLIB,"Invalid TSStepStatus"); 933 } 934 ierr = PetscMalloc2(s,&bt,s,&b);CHKERRQ(ierr); 935 for (i=0; i<s; i++) bt[i] = b[i] = 0; 936 for (j=0,tt=t; j<pinterp; j++,tt*=t) { 937 for (i=0; i<s; i++) { 938 bt[i] += h * Bt[i*pinterp+j] * tt; 939 b[i] += h * B[i*pinterp+j] * tt; 940 } 941 } 942 ierr = VecCopy(ark->Y[0],X);CHKERRQ(ierr); 943 ierr = VecMAXPY(X,s,bt,ark->YdotI);CHKERRQ(ierr); 944 ierr = VecMAXPY(X,s,b,ark->YdotRHS);CHKERRQ(ierr); 945 ierr = PetscFree2(bt,b);CHKERRQ(ierr); 946 PetscFunctionReturn(0); 947 } 948 949 static PetscErrorCode TSExtrapolate_ARKIMEX(TS ts,PetscReal c,Vec X) 950 { 951 TS_ARKIMEX *ark = (TS_ARKIMEX*)ts->data; 952 PetscInt s = ark->tableau->s,pinterp = ark->tableau->pinterp,i,j; 953 PetscReal h,h_prev,t,tt; 954 PetscScalar *bt,*b; 955 const PetscReal *Bt = ark->tableau->binterpt,*B = ark->tableau->binterp; 956 PetscErrorCode ierr; 957 958 PetscFunctionBegin; 959 if (!Bt || !B) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSARKIMEX %s does not have an interpolation formula",ark->tableau->name); 960 ierr = PetscCalloc2(s,&bt,s,&b);CHKERRQ(ierr); 961 h = ts->time_step; 962 h_prev = ts->ptime - ts->ptime_prev; 963 t = 1 + h/h_prev*c; 964 for (j=0,tt=t; j<pinterp; j++,tt*=t) { 965 for (i=0; i<s; i++) { 966 bt[i] += h * Bt[i*pinterp+j] * tt; 967 b[i] += h * B[i*pinterp+j] * tt; 968 } 969 } 970 if (!ark->Y_prev) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Stages from previous step have not been stored"); 971 ierr = VecCopy(ark->Y_prev[0],X);CHKERRQ(ierr); 972 ierr = VecMAXPY(X,s,bt,ark->YdotI_prev);CHKERRQ(ierr); 973 ierr = VecMAXPY(X,s,b,ark->YdotRHS_prev);CHKERRQ(ierr); 974 ierr = PetscFree2(bt,b);CHKERRQ(ierr); 975 PetscFunctionReturn(0); 976 } 977 978 /*------------------------------------------------------------*/ 979 980 static PetscErrorCode TSARKIMEXTableauReset(TS ts) 981 { 982 TS_ARKIMEX *ark = (TS_ARKIMEX*)ts->data; 983 ARKTableau tab = ark->tableau; 984 PetscErrorCode ierr; 985 986 PetscFunctionBegin; 987 if (!tab) PetscFunctionReturn(0); 988 ierr = PetscFree(ark->work);CHKERRQ(ierr); 989 ierr = VecDestroyVecs(tab->s,&ark->Y);CHKERRQ(ierr); 990 ierr = VecDestroyVecs(tab->s,&ark->YdotI);CHKERRQ(ierr); 991 ierr = VecDestroyVecs(tab->s,&ark->YdotRHS);CHKERRQ(ierr); 992 ierr = VecDestroyVecs(tab->s,&ark->Y_prev);CHKERRQ(ierr); 993 ierr = VecDestroyVecs(tab->s,&ark->YdotI_prev);CHKERRQ(ierr); 994 ierr = VecDestroyVecs(tab->s,&ark->YdotRHS_prev);CHKERRQ(ierr); 995 PetscFunctionReturn(0); 996 } 997 998 static PetscErrorCode TSReset_ARKIMEX(TS ts) 999 { 1000 TS_ARKIMEX *ark = (TS_ARKIMEX*)ts->data; 1001 PetscErrorCode ierr; 1002 1003 PetscFunctionBegin; 1004 ierr = TSARKIMEXTableauReset(ts);CHKERRQ(ierr); 1005 ierr = VecDestroy(&ark->Ydot);CHKERRQ(ierr); 1006 ierr = VecDestroy(&ark->Ydot0);CHKERRQ(ierr); 1007 ierr = VecDestroy(&ark->Z);CHKERRQ(ierr); 1008 PetscFunctionReturn(0); 1009 } 1010 1011 static PetscErrorCode TSARKIMEXGetVecs(TS ts,DM dm,Vec *Z,Vec *Ydot) 1012 { 1013 TS_ARKIMEX *ax = (TS_ARKIMEX*)ts->data; 1014 PetscErrorCode ierr; 1015 1016 PetscFunctionBegin; 1017 if (Z) { 1018 if (dm && dm != ts->dm) { 1019 ierr = DMGetNamedGlobalVector(dm,"TSARKIMEX_Z",Z);CHKERRQ(ierr); 1020 } else *Z = ax->Z; 1021 } 1022 if (Ydot) { 1023 if (dm && dm != ts->dm) { 1024 ierr = DMGetNamedGlobalVector(dm,"TSARKIMEX_Ydot",Ydot);CHKERRQ(ierr); 1025 } else *Ydot = ax->Ydot; 1026 } 1027 PetscFunctionReturn(0); 1028 } 1029 1030 static PetscErrorCode TSARKIMEXRestoreVecs(TS ts,DM dm,Vec *Z,Vec *Ydot) 1031 { 1032 PetscErrorCode ierr; 1033 1034 PetscFunctionBegin; 1035 if (Z) { 1036 if (dm && dm != ts->dm) { 1037 ierr = DMRestoreNamedGlobalVector(dm,"TSARKIMEX_Z",Z);CHKERRQ(ierr); 1038 } 1039 } 1040 if (Ydot) { 1041 if (dm && dm != ts->dm) { 1042 ierr = DMRestoreNamedGlobalVector(dm,"TSARKIMEX_Ydot",Ydot);CHKERRQ(ierr); 1043 } 1044 } 1045 PetscFunctionReturn(0); 1046 } 1047 1048 /* 1049 This defines the nonlinear equation that is to be solved with SNES 1050 G(U) = F[t0+Theta*dt, U, (U-U0)*shift] = 0 1051 */ 1052 static PetscErrorCode SNESTSFormFunction_ARKIMEX(SNES snes,Vec X,Vec F,TS ts) 1053 { 1054 TS_ARKIMEX *ark = (TS_ARKIMEX*)ts->data; 1055 DM dm,dmsave; 1056 Vec Z,Ydot; 1057 PetscReal shift = ark->scoeff / ts->time_step; 1058 PetscErrorCode ierr; 1059 1060 PetscFunctionBegin; 1061 ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 1062 ierr = TSARKIMEXGetVecs(ts,dm,&Z,&Ydot);CHKERRQ(ierr); 1063 ierr = VecAXPBYPCZ(Ydot,-shift,shift,0,Z,X);CHKERRQ(ierr); /* Ydot = shift*(X-Z) */ 1064 dmsave = ts->dm; 1065 ts->dm = dm; 1066 1067 ierr = TSComputeIFunction(ts,ark->stage_time,X,Ydot,F,ark->imex);CHKERRQ(ierr); 1068 1069 ts->dm = dmsave; 1070 ierr = TSARKIMEXRestoreVecs(ts,dm,&Z,&Ydot);CHKERRQ(ierr); 1071 PetscFunctionReturn(0); 1072 } 1073 1074 static PetscErrorCode SNESTSFormJacobian_ARKIMEX(SNES snes,Vec X,Mat A,Mat B,TS ts) 1075 { 1076 TS_ARKIMEX *ark = (TS_ARKIMEX*)ts->data; 1077 DM dm,dmsave; 1078 Vec Ydot; 1079 PetscReal shift = ark->scoeff / ts->time_step; 1080 PetscErrorCode ierr; 1081 1082 PetscFunctionBegin; 1083 ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 1084 ierr = TSARKIMEXGetVecs(ts,dm,NULL,&Ydot);CHKERRQ(ierr); 1085 /* ark->Ydot has already been computed in SNESTSFormFunction_ARKIMEX (SNES guarantees this) */ 1086 dmsave = ts->dm; 1087 ts->dm = dm; 1088 1089 ierr = TSComputeIJacobian(ts,ark->stage_time,X,Ydot,shift,A,B,ark->imex);CHKERRQ(ierr); 1090 1091 ts->dm = dmsave; 1092 ierr = TSARKIMEXRestoreVecs(ts,dm,NULL,&Ydot);CHKERRQ(ierr); 1093 PetscFunctionReturn(0); 1094 } 1095 1096 static PetscErrorCode DMCoarsenHook_TSARKIMEX(DM fine,DM coarse,void *ctx) 1097 { 1098 PetscFunctionBegin; 1099 PetscFunctionReturn(0); 1100 } 1101 1102 static PetscErrorCode DMRestrictHook_TSARKIMEX(DM fine,Mat restrct,Vec rscale,Mat inject,DM coarse,void *ctx) 1103 { 1104 TS ts = (TS)ctx; 1105 PetscErrorCode ierr; 1106 Vec Z,Z_c; 1107 1108 PetscFunctionBegin; 1109 ierr = TSARKIMEXGetVecs(ts,fine,&Z,NULL);CHKERRQ(ierr); 1110 ierr = TSARKIMEXGetVecs(ts,coarse,&Z_c,NULL);CHKERRQ(ierr); 1111 ierr = MatRestrict(restrct,Z,Z_c);CHKERRQ(ierr); 1112 ierr = VecPointwiseMult(Z_c,rscale,Z_c);CHKERRQ(ierr); 1113 ierr = TSARKIMEXRestoreVecs(ts,fine,&Z,NULL);CHKERRQ(ierr); 1114 ierr = TSARKIMEXRestoreVecs(ts,coarse,&Z_c,NULL);CHKERRQ(ierr); 1115 PetscFunctionReturn(0); 1116 } 1117 1118 static PetscErrorCode DMSubDomainHook_TSARKIMEX(DM dm,DM subdm,void *ctx) 1119 { 1120 PetscFunctionBegin; 1121 PetscFunctionReturn(0); 1122 } 1123 1124 static PetscErrorCode DMSubDomainRestrictHook_TSARKIMEX(DM dm,VecScatter gscat,VecScatter lscat,DM subdm,void *ctx) 1125 { 1126 TS ts = (TS)ctx; 1127 PetscErrorCode ierr; 1128 Vec Z,Z_c; 1129 1130 PetscFunctionBegin; 1131 ierr = TSARKIMEXGetVecs(ts,dm,&Z,NULL);CHKERRQ(ierr); 1132 ierr = TSARKIMEXGetVecs(ts,subdm,&Z_c,NULL);CHKERRQ(ierr); 1133 1134 ierr = VecScatterBegin(gscat,Z,Z_c,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1135 ierr = VecScatterEnd(gscat,Z,Z_c,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1136 1137 ierr = TSARKIMEXRestoreVecs(ts,dm,&Z,NULL);CHKERRQ(ierr); 1138 ierr = TSARKIMEXRestoreVecs(ts,subdm,&Z_c,NULL);CHKERRQ(ierr); 1139 PetscFunctionReturn(0); 1140 } 1141 1142 static PetscErrorCode TSARKIMEXTableauSetUp(TS ts) 1143 { 1144 TS_ARKIMEX *ark = (TS_ARKIMEX*)ts->data; 1145 ARKTableau tab = ark->tableau; 1146 PetscErrorCode ierr; 1147 1148 PetscFunctionBegin; 1149 ierr = PetscMalloc1(tab->s,&ark->work);CHKERRQ(ierr); 1150 ierr = VecDuplicateVecs(ts->vec_sol,tab->s,&ark->Y);CHKERRQ(ierr); 1151 ierr = VecDuplicateVecs(ts->vec_sol,tab->s,&ark->YdotI);CHKERRQ(ierr); 1152 ierr = VecDuplicateVecs(ts->vec_sol,tab->s,&ark->YdotRHS);CHKERRQ(ierr); 1153 if (ark->extrapolate) { 1154 ierr = VecDuplicateVecs(ts->vec_sol,tab->s,&ark->Y_prev);CHKERRQ(ierr); 1155 ierr = VecDuplicateVecs(ts->vec_sol,tab->s,&ark->YdotI_prev);CHKERRQ(ierr); 1156 ierr = VecDuplicateVecs(ts->vec_sol,tab->s,&ark->YdotRHS_prev);CHKERRQ(ierr); 1157 } 1158 PetscFunctionReturn(0); 1159 } 1160 1161 static PetscErrorCode TSSetUp_ARKIMEX(TS ts) 1162 { 1163 TS_ARKIMEX *ark = (TS_ARKIMEX*)ts->data; 1164 PetscErrorCode ierr; 1165 DM dm; 1166 SNES snes; 1167 1168 PetscFunctionBegin; 1169 ierr = TSARKIMEXTableauSetUp(ts);CHKERRQ(ierr); 1170 ierr = VecDuplicate(ts->vec_sol,&ark->Ydot);CHKERRQ(ierr); 1171 ierr = VecDuplicate(ts->vec_sol,&ark->Ydot0);CHKERRQ(ierr); 1172 ierr = VecDuplicate(ts->vec_sol,&ark->Z);CHKERRQ(ierr); 1173 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1174 ierr = DMCoarsenHookAdd(dm,DMCoarsenHook_TSARKIMEX,DMRestrictHook_TSARKIMEX,ts);CHKERRQ(ierr); 1175 ierr = DMSubDomainHookAdd(dm,DMSubDomainHook_TSARKIMEX,DMSubDomainRestrictHook_TSARKIMEX,ts);CHKERRQ(ierr); 1176 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1177 PetscFunctionReturn(0); 1178 } 1179 /*------------------------------------------------------------*/ 1180 1181 static PetscErrorCode TSSetFromOptions_ARKIMEX(PetscOptionItems *PetscOptionsObject,TS ts) 1182 { 1183 TS_ARKIMEX *ark = (TS_ARKIMEX*)ts->data; 1184 PetscErrorCode ierr; 1185 1186 PetscFunctionBegin; 1187 ierr = PetscOptionsHead(PetscOptionsObject,"ARKIMEX ODE solver options");CHKERRQ(ierr); 1188 { 1189 ARKTableauLink link; 1190 PetscInt count,choice; 1191 PetscBool flg; 1192 const char **namelist; 1193 for (link=ARKTableauList,count=0; link; link=link->next,count++) ; 1194 ierr = PetscMalloc1(count,(char***)&namelist);CHKERRQ(ierr); 1195 for (link=ARKTableauList,count=0; link; link=link->next,count++) namelist[count] = link->tab.name; 1196 ierr = PetscOptionsEList("-ts_arkimex_type","Family of ARK IMEX method","TSARKIMEXSetType",(const char*const*)namelist,count,ark->tableau->name,&choice,&flg);CHKERRQ(ierr); 1197 if (flg) {ierr = TSARKIMEXSetType(ts,namelist[choice]);CHKERRQ(ierr);} 1198 ierr = PetscFree(namelist);CHKERRQ(ierr); 1199 1200 flg = (PetscBool) !ark->imex; 1201 ierr = PetscOptionsBool("-ts_arkimex_fully_implicit","Solve the problem fully implicitly","TSARKIMEXSetFullyImplicit",flg,&flg,NULL);CHKERRQ(ierr); 1202 ark->imex = (PetscBool) !flg; 1203 ierr = PetscOptionsBool("-ts_arkimex_initial_guess_extrapolate","Extrapolate the initial guess for the stage solution from stage values of the previous time step","",ark->extrapolate,&ark->extrapolate,NULL);CHKERRQ(ierr); 1204 } 1205 ierr = PetscOptionsTail();CHKERRQ(ierr); 1206 PetscFunctionReturn(0); 1207 } 1208 1209 static PetscErrorCode TSView_ARKIMEX(TS ts,PetscViewer viewer) 1210 { 1211 TS_ARKIMEX *ark = (TS_ARKIMEX*)ts->data; 1212 PetscBool iascii; 1213 PetscErrorCode ierr; 1214 1215 PetscFunctionBegin; 1216 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 1217 if (iascii) { 1218 ARKTableau tab = ark->tableau; 1219 TSARKIMEXType arktype; 1220 char buf[512]; 1221 PetscBool flg; 1222 1223 ierr = TSARKIMEXGetType(ts,&arktype);CHKERRQ(ierr); 1224 ierr = TSARKIMEXGetFullyImplicit(ts,&flg);CHKERRQ(ierr); 1225 ierr = PetscViewerASCIIPrintf(viewer," ARK IMEX %s\n",arktype);CHKERRQ(ierr); 1226 ierr = PetscFormatRealArray(buf,sizeof(buf),"% 8.6f",tab->s,tab->ct);CHKERRQ(ierr); 1227 ierr = PetscViewerASCIIPrintf(viewer," Stiff abscissa ct = %s\n",buf);CHKERRQ(ierr); 1228 ierr = PetscFormatRealArray(buf,sizeof(buf),"% 8.6f",tab->s,tab->c);CHKERRQ(ierr); 1229 ierr = PetscViewerASCIIPrintf(viewer,"Fully implicit: %s\n",flg ? "yes" : "no");CHKERRQ(ierr); 1230 ierr = PetscViewerASCIIPrintf(viewer,"Stiffly accurate: %s\n",tab->stiffly_accurate ? "yes" : "no");CHKERRQ(ierr); 1231 ierr = PetscViewerASCIIPrintf(viewer,"Explicit first stage: %s\n",tab->explicit_first_stage ? "yes" : "no");CHKERRQ(ierr); 1232 ierr = PetscViewerASCIIPrintf(viewer,"FSAL property: %s\n",tab->FSAL_implicit ? "yes" : "no");CHKERRQ(ierr); 1233 ierr = PetscViewerASCIIPrintf(viewer," Nonstiff abscissa c = %s\n",buf);CHKERRQ(ierr); 1234 } 1235 PetscFunctionReturn(0); 1236 } 1237 1238 static PetscErrorCode TSLoad_ARKIMEX(TS ts,PetscViewer viewer) 1239 { 1240 PetscErrorCode ierr; 1241 SNES snes; 1242 TSAdapt adapt; 1243 1244 PetscFunctionBegin; 1245 ierr = TSGetAdapt(ts,&adapt);CHKERRQ(ierr); 1246 ierr = TSAdaptLoad(adapt,viewer);CHKERRQ(ierr); 1247 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1248 ierr = SNESLoad(snes,viewer);CHKERRQ(ierr); 1249 /* function and Jacobian context for SNES when used with TS is always ts object */ 1250 ierr = SNESSetFunction(snes,NULL,NULL,ts);CHKERRQ(ierr); 1251 ierr = SNESSetJacobian(snes,NULL,NULL,NULL,ts);CHKERRQ(ierr); 1252 PetscFunctionReturn(0); 1253 } 1254 1255 /*@C 1256 TSARKIMEXSetType - Set the type of ARK IMEX scheme 1257 1258 Logically collective 1259 1260 Input Parameters: 1261 + ts - timestepping context 1262 - arktype - type of ARK-IMEX scheme 1263 1264 Options Database: 1265 . -ts_arkimex_type <1bee,a2,l2,ars122,2c,2d,2e,prssp2,3,bpr3,ars443,4,5> 1266 1267 Level: intermediate 1268 1269 .seealso: TSARKIMEXGetType(), TSARKIMEX, TSARKIMEXType, TSARKIMEX1BEE, TSARKIMEXA2, TSARKIMEXL2, TSARKIMEXARS122, TSARKIMEX2C, TSARKIMEX2D, TSARKIMEX2E, TSARKIMEXPRSSP2, 1270 TSARKIMEX3, TSARKIMEXBPR3, TSARKIMEXARS443, TSARKIMEX4, TSARKIMEX5 1271 @*/ 1272 PetscErrorCode TSARKIMEXSetType(TS ts,TSARKIMEXType arktype) 1273 { 1274 PetscErrorCode ierr; 1275 1276 PetscFunctionBegin; 1277 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1278 PetscValidCharPointer(arktype,2); 1279 ierr = PetscTryMethod(ts,"TSARKIMEXSetType_C",(TS,TSARKIMEXType),(ts,arktype));CHKERRQ(ierr); 1280 PetscFunctionReturn(0); 1281 } 1282 1283 /*@C 1284 TSARKIMEXGetType - Get the type of ARK IMEX scheme 1285 1286 Logically collective 1287 1288 Input Parameter: 1289 . ts - timestepping context 1290 1291 Output Parameter: 1292 . arktype - type of ARK-IMEX scheme 1293 1294 Level: intermediate 1295 1296 .seealso: TSARKIMEXGetType() 1297 @*/ 1298 PetscErrorCode TSARKIMEXGetType(TS ts,TSARKIMEXType *arktype) 1299 { 1300 PetscErrorCode ierr; 1301 1302 PetscFunctionBegin; 1303 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1304 ierr = PetscUseMethod(ts,"TSARKIMEXGetType_C",(TS,TSARKIMEXType*),(ts,arktype));CHKERRQ(ierr); 1305 PetscFunctionReturn(0); 1306 } 1307 1308 /*@ 1309 TSARKIMEXSetFullyImplicit - Solve both parts of the equation implicitly 1310 1311 Logically collective 1312 1313 Input Parameters: 1314 + ts - timestepping context 1315 - flg - PETSC_TRUE for fully implicit 1316 1317 Level: intermediate 1318 1319 .seealso: TSARKIMEXGetType(), TSARKIMEXGetFullyImplicit() 1320 @*/ 1321 PetscErrorCode TSARKIMEXSetFullyImplicit(TS ts,PetscBool flg) 1322 { 1323 PetscErrorCode ierr; 1324 1325 PetscFunctionBegin; 1326 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1327 PetscValidLogicalCollectiveBool(ts,flg,2); 1328 ierr = PetscTryMethod(ts,"TSARKIMEXSetFullyImplicit_C",(TS,PetscBool),(ts,flg));CHKERRQ(ierr); 1329 PetscFunctionReturn(0); 1330 } 1331 1332 /*@ 1333 TSARKIMEXGetFullyImplicit - Inquires if both parts of the equation are solved implicitly 1334 1335 Logically collective 1336 1337 Input Parameter: 1338 . ts - timestepping context 1339 1340 Output Parameter: 1341 . flg - PETSC_TRUE for fully implicit 1342 1343 Level: intermediate 1344 1345 .seealso: TSARKIMEXGetType(), TSARKIMEXSetFullyImplicit() 1346 @*/ 1347 PetscErrorCode TSARKIMEXGetFullyImplicit(TS ts,PetscBool *flg) 1348 { 1349 PetscErrorCode ierr; 1350 1351 PetscFunctionBegin; 1352 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1353 PetscValidPointer(flg,2); 1354 ierr = PetscUseMethod(ts,"TSARKIMEXGetFullyImplicit_C",(TS,PetscBool*),(ts,flg));CHKERRQ(ierr); 1355 PetscFunctionReturn(0); 1356 } 1357 1358 static PetscErrorCode TSARKIMEXGetType_ARKIMEX(TS ts,TSARKIMEXType *arktype) 1359 { 1360 TS_ARKIMEX *ark = (TS_ARKIMEX*)ts->data; 1361 1362 PetscFunctionBegin; 1363 *arktype = ark->tableau->name; 1364 PetscFunctionReturn(0); 1365 } 1366 static PetscErrorCode TSARKIMEXSetType_ARKIMEX(TS ts,TSARKIMEXType arktype) 1367 { 1368 TS_ARKIMEX *ark = (TS_ARKIMEX*)ts->data; 1369 PetscErrorCode ierr; 1370 PetscBool match; 1371 ARKTableauLink link; 1372 1373 PetscFunctionBegin; 1374 if (ark->tableau) { 1375 ierr = PetscStrcmp(ark->tableau->name,arktype,&match);CHKERRQ(ierr); 1376 if (match) PetscFunctionReturn(0); 1377 } 1378 for (link = ARKTableauList; link; link=link->next) { 1379 ierr = PetscStrcmp(link->tab.name,arktype,&match);CHKERRQ(ierr); 1380 if (match) { 1381 if (ts->setupcalled) {ierr = TSARKIMEXTableauReset(ts);CHKERRQ(ierr);} 1382 ark->tableau = &link->tab; 1383 if (ts->setupcalled) {ierr = TSARKIMEXTableauSetUp(ts);CHKERRQ(ierr);} 1384 ts->default_adapt_type = ark->tableau->bembed ? TSADAPTBASIC : TSADAPTNONE; 1385 PetscFunctionReturn(0); 1386 } 1387 } 1388 SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_UNKNOWN_TYPE,"Could not find '%s'",arktype); 1389 } 1390 1391 static PetscErrorCode TSARKIMEXSetFullyImplicit_ARKIMEX(TS ts,PetscBool flg) 1392 { 1393 TS_ARKIMEX *ark = (TS_ARKIMEX*)ts->data; 1394 1395 PetscFunctionBegin; 1396 ark->imex = (PetscBool)!flg; 1397 PetscFunctionReturn(0); 1398 } 1399 1400 static PetscErrorCode TSARKIMEXGetFullyImplicit_ARKIMEX(TS ts,PetscBool *flg) 1401 { 1402 TS_ARKIMEX *ark = (TS_ARKIMEX*)ts->data; 1403 1404 PetscFunctionBegin; 1405 *flg = (PetscBool)!ark->imex; 1406 PetscFunctionReturn(0); 1407 } 1408 1409 static PetscErrorCode TSDestroy_ARKIMEX(TS ts) 1410 { 1411 PetscErrorCode ierr; 1412 1413 PetscFunctionBegin; 1414 ierr = TSReset_ARKIMEX(ts);CHKERRQ(ierr); 1415 if (ts->dm) { 1416 ierr = DMCoarsenHookRemove(ts->dm,DMCoarsenHook_TSARKIMEX,DMRestrictHook_TSARKIMEX,ts);CHKERRQ(ierr); 1417 ierr = DMSubDomainHookRemove(ts->dm,DMSubDomainHook_TSARKIMEX,DMSubDomainRestrictHook_TSARKIMEX,ts);CHKERRQ(ierr); 1418 } 1419 ierr = PetscFree(ts->data);CHKERRQ(ierr); 1420 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSARKIMEXGetType_C",NULL);CHKERRQ(ierr); 1421 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSARKIMEXSetType_C",NULL);CHKERRQ(ierr); 1422 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSARKIMEXSetFullyImplicit_C",NULL);CHKERRQ(ierr); 1423 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSARKIMEXSetFullyImplicit_C",NULL);CHKERRQ(ierr); 1424 PetscFunctionReturn(0); 1425 } 1426 1427 /* ------------------------------------------------------------ */ 1428 /*MC 1429 TSARKIMEX - ODE and DAE solver using additive Runge-Kutta IMEX schemes 1430 1431 These methods are intended for problems with well-separated time scales, especially when a slow scale is strongly 1432 nonlinear such that it is expensive to solve with a fully implicit method. The user should provide the stiff part 1433 of the equation using TSSetIFunction() and the non-stiff part with TSSetRHSFunction(). 1434 1435 Notes: 1436 The default is TSARKIMEX3, it can be changed with TSARKIMEXSetType() or -ts_arkimex_type 1437 1438 If the equation is implicit or a DAE, then TSSetEquationType() needs to be set accordingly. Refer to the manual for further information. 1439 1440 Methods with an explicit stage can only be used with ODE in which the stiff part G(t,X,Xdot) has the form Xdot + Ghat(t,X). 1441 1442 Consider trying TSROSW if the stiff part is linear or weakly nonlinear. 1443 1444 Level: beginner 1445 1446 .seealso: TSCreate(), TS, TSSetType(), TSARKIMEXSetType(), TSARKIMEXGetType(), TSARKIMEXSetFullyImplicit(), TSARKIMEXGetFullyImplicit(), 1447 TSARKIMEX1BEE, TSARKIMEX2C, TSARKIMEX2D, TSARKIMEX2E, TSARKIMEX3, TSARKIMEXL2, TSARKIMEXA2, TSARKIMEXARS122, 1448 TSARKIMEX4, TSARKIMEX5, TSARKIMEXPRSSP2, TSARKIMEXARS443, TSARKIMEXBPR3, TSARKIMEXType, TSARKIMEXRegister() 1449 1450 M*/ 1451 PETSC_EXTERN PetscErrorCode TSCreate_ARKIMEX(TS ts) 1452 { 1453 TS_ARKIMEX *th; 1454 PetscErrorCode ierr; 1455 1456 PetscFunctionBegin; 1457 ierr = TSARKIMEXInitializePackage();CHKERRQ(ierr); 1458 1459 ts->ops->reset = TSReset_ARKIMEX; 1460 ts->ops->destroy = TSDestroy_ARKIMEX; 1461 ts->ops->view = TSView_ARKIMEX; 1462 ts->ops->load = TSLoad_ARKIMEX; 1463 ts->ops->setup = TSSetUp_ARKIMEX; 1464 ts->ops->step = TSStep_ARKIMEX; 1465 ts->ops->interpolate = TSInterpolate_ARKIMEX; 1466 ts->ops->evaluatestep = TSEvaluateStep_ARKIMEX; 1467 ts->ops->rollback = TSRollBack_ARKIMEX; 1468 ts->ops->setfromoptions = TSSetFromOptions_ARKIMEX; 1469 ts->ops->snesfunction = SNESTSFormFunction_ARKIMEX; 1470 ts->ops->snesjacobian = SNESTSFormJacobian_ARKIMEX; 1471 1472 ts->usessnes = PETSC_TRUE; 1473 1474 ierr = PetscNewLog(ts,&th);CHKERRQ(ierr); 1475 ts->data = (void*)th; 1476 th->imex = PETSC_TRUE; 1477 1478 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSARKIMEXGetType_C",TSARKIMEXGetType_ARKIMEX);CHKERRQ(ierr); 1479 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSARKIMEXSetType_C",TSARKIMEXSetType_ARKIMEX);CHKERRQ(ierr); 1480 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSARKIMEXSetFullyImplicit_C",TSARKIMEXSetFullyImplicit_ARKIMEX);CHKERRQ(ierr); 1481 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSARKIMEXGetFullyImplicit_C",TSARKIMEXGetFullyImplicit_ARKIMEX);CHKERRQ(ierr); 1482 1483 ierr = TSARKIMEXSetType(ts,TSARKIMEXDefault);CHKERRQ(ierr); 1484 PetscFunctionReturn(0); 1485 } 1486