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