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