1 /* 2 Code for time stepping with the Runge-Kutta method 3 4 Notes: 5 The general system is written as 6 7 Udot = F(t,U) 8 9 */ 10 #include <petsc/private/tsimpl.h> /*I "petscts.h" I*/ 11 #include <petscdm.h> 12 13 static TSRKType TSRKDefault = TSRK3BS; 14 static PetscBool TSRKRegisterAllCalled; 15 static PetscBool TSRKPackageInitialized; 16 17 typedef struct _RKTableau *RKTableau; 18 struct _RKTableau { 19 char *name; 20 PetscInt order; /* Classical approximation order of the method i */ 21 PetscInt s; /* Number of stages */ 22 PetscInt p; /* Interpolation order */ 23 PetscBool FSAL; /* flag to indicate if tableau is FSAL */ 24 PetscReal *A,*b,*c; /* Tableau */ 25 PetscReal *bembed; /* Embedded formula of order one less (order-1) */ 26 PetscReal *binterp; /* Dense output formula */ 27 PetscReal ccfl; /* Placeholder for CFL coefficient relative to forward Euler */ 28 }; 29 typedef struct _RKTableauLink *RKTableauLink; 30 struct _RKTableauLink { 31 struct _RKTableau tab; 32 RKTableauLink next; 33 }; 34 static RKTableauLink RKTableauList; 35 36 typedef struct { 37 RKTableau tableau; 38 Vec *Y; /* States computed during the step */ 39 Vec *YdotRHS; /* Function evaluations for the non-stiff part */ 40 Vec *VecDeltaLam; /* Increment of the adjoint sensitivity w.r.t IC at stage */ 41 Vec *VecDeltaMu; /* Increment of the adjoint sensitivity w.r.t P at stage */ 42 Vec VecCostIntegral0; /* backup for roll-backs due to events */ 43 PetscScalar *work; /* Scalar work */ 44 PetscReal stage_time; 45 TSStepStatus status; 46 PetscReal ptime; 47 PetscReal time_step; 48 } TS_RK; 49 50 /*MC 51 TSRK1FE - First order forward Euler scheme. 52 53 This method has one stage. 54 55 Options database: 56 . -ts_rk_type 1fe 57 58 Level: advanced 59 60 .seealso: TSRK, TSRKType, TSRKSetType() 61 M*/ 62 /*MC 63 TSRK2A - Second order RK scheme. 64 65 This method has two stages. 66 67 Options database: 68 . -ts_rk_type 2a 69 70 Level: advanced 71 72 .seealso: TSRK, TSRKType, TSRKSetType() 73 M*/ 74 /*MC 75 TSRK3 - Third order RK scheme. 76 77 This method has three stages. 78 79 Options database: 80 . -ts_rk_type 3 81 82 Level: advanced 83 84 .seealso: TSRK, TSRKType, TSRKSetType() 85 M*/ 86 /*MC 87 TSRK3BS - Third order RK scheme of Bogacki-Shampine with 2nd order embedded method. 88 89 This method has four stages with the First Same As Last (FSAL) property. 90 91 Options database: 92 . -ts_rk_type 3bs 93 94 Level: advanced 95 96 References: https://doi.org/10.1016/0893-9659(89)90079-7 97 98 .seealso: TSRK, TSRKType, TSRKSetType() 99 M*/ 100 /*MC 101 TSRK4 - Fourth order RK scheme. 102 103 This is the classical Runge-Kutta method with four stages. 104 105 Options database: 106 . -ts_rk_type 4 107 108 Level: advanced 109 110 .seealso: TSRK, TSRKType, TSRKSetType() 111 M*/ 112 /*MC 113 TSRK5F - Fifth order Fehlberg RK scheme with a 4th order embedded method. 114 115 This method has six stages. 116 117 Options database: 118 . -ts_rk_type 5f 119 120 Level: advanced 121 122 .seealso: TSRK, TSRKType, TSRKSetType() 123 M*/ 124 /*MC 125 TSRK5DP - Fifth order Dormand-Prince RK scheme with the 4th order embedded method. 126 127 This method has seven stages with the First Same As Last (FSAL) property. 128 129 Options database: 130 . -ts_rk_type 5dp 131 132 Level: advanced 133 134 References: https://doi.org/10.1016/0771-050X(80)90013-3 135 136 .seealso: TSRK, TSRKType, TSRKSetType() 137 M*/ 138 /*MC 139 TSRK5BS - Fifth order Bogacki-Shampine RK scheme with 4th order embedded method. 140 141 This method has eight stages with the First Same As Last (FSAL) property. 142 143 Options database: 144 . -ts_rk_type 5bs 145 146 Level: advanced 147 148 References: https://doi.org/10.1016/0898-1221(96)00141-1 149 150 .seealso: TSRK, TSRKType, TSRKSetType() 151 M*/ 152 153 /*@C 154 TSRKRegisterAll - Registers all of the Runge-Kutta explicit methods in TSRK 155 156 Not Collective, but should be called by all processes which will need the schemes to be registered 157 158 Level: advanced 159 160 .keywords: TS, TSRK, register, all 161 162 .seealso: TSRKRegisterDestroy() 163 @*/ 164 PetscErrorCode TSRKRegisterAll(void) 165 { 166 PetscErrorCode ierr; 167 168 PetscFunctionBegin; 169 if (TSRKRegisterAllCalled) PetscFunctionReturn(0); 170 TSRKRegisterAllCalled = PETSC_TRUE; 171 172 #define RC PetscRealConstant 173 { 174 const PetscReal 175 A[1][1] = {{0}}, 176 b[1] = {RC(1.0)}; 177 ierr = TSRKRegister(TSRK1FE,1,1,&A[0][0],b,NULL,NULL,0,NULL);CHKERRQ(ierr); 178 } 179 { 180 const PetscReal 181 A[2][2] = {{0,0}, 182 {RC(1.0),0}}, 183 b[2] = {RC(0.5),RC(0.5)}, 184 bembed[2] = {RC(1.0),0}; 185 ierr = TSRKRegister(TSRK2A,2,2,&A[0][0],b,NULL,bembed,0,NULL);CHKERRQ(ierr); 186 } 187 { 188 const PetscReal 189 A[3][3] = {{0,0,0}, 190 {RC(2.0)/RC(3.0),0,0}, 191 {RC(-1.0)/RC(3.0),RC(1.0),0}}, 192 b[3] = {RC(0.25),RC(0.5),RC(0.25)}; 193 ierr = TSRKRegister(TSRK3,3,3,&A[0][0],b,NULL,NULL,0,NULL);CHKERRQ(ierr); 194 } 195 { 196 const PetscReal 197 A[4][4] = {{0,0,0,0}, 198 {RC(1.0)/RC(2.0),0,0,0}, 199 {0,RC(3.0)/RC(4.0),0,0}, 200 {RC(2.0)/RC(9.0),RC(1.0)/RC(3.0),RC(4.0)/RC(9.0),0}}, 201 b[4] = {RC(2.0)/RC(9.0),RC(1.0)/RC(3.0),RC(4.0)/RC(9.0),0}, 202 bembed[4] = {RC(7.0)/RC(24.0),RC(1.0)/RC(4.0),RC(1.0)/RC(3.0),RC(1.0)/RC(8.0)}; 203 ierr = TSRKRegister(TSRK3BS,3,4,&A[0][0],b,NULL,bembed,0,NULL);CHKERRQ(ierr); 204 } 205 { 206 const PetscReal 207 A[4][4] = {{0,0,0,0}, 208 {RC(0.5),0,0,0}, 209 {0,RC(0.5),0,0}, 210 {0,0,RC(1.0),0}}, 211 b[4] = {RC(1.0)/RC(6.0),RC(1.0)/RC(3.0),RC(1.0)/RC(3.0),RC(1.0)/RC(6.0)}; 212 ierr = TSRKRegister(TSRK4,4,4,&A[0][0],b,NULL,NULL,0,NULL);CHKERRQ(ierr); 213 } 214 { 215 const PetscReal 216 A[6][6] = {{0,0,0,0,0,0}, 217 {RC(0.25),0,0,0,0,0}, 218 {RC(3.0)/RC(32.0),RC(9.0)/RC(32.0),0,0,0,0}, 219 {RC(1932.0)/RC(2197.0),RC(-7200.0)/RC(2197.0),RC(7296.0)/RC(2197.0),0,0,0}, 220 {RC(439.0)/RC(216.0),RC(-8.0),RC(3680.0)/RC(513.0),RC(-845.0)/RC(4104.0),0,0}, 221 {RC(-8.0)/RC(27.0),RC(2.0),RC(-3544.0)/RC(2565.0),RC(1859.0)/RC(4104.0),RC(-11.0)/RC(40.0),0}}, 222 b[6] = {RC(16.0)/RC(135.0),0,RC(6656.0)/RC(12825.0),RC(28561.0)/RC(56430.0),RC(-9.0)/RC(50.0),RC(2.0)/RC(55.0)}, 223 bembed[6] = {RC(25.0)/RC(216.0),0,RC(1408.0)/RC(2565.0),RC(2197.0)/RC(4104.0),RC(-1.0)/RC(5.0),0}; 224 ierr = TSRKRegister(TSRK5F,5,6,&A[0][0],b,NULL,bembed,0,NULL);CHKERRQ(ierr); 225 } 226 { 227 const PetscReal 228 A[7][7] = {{0,0,0,0,0,0,0}, 229 {RC(1.0)/RC(5.0),0,0,0,0,0,0}, 230 {RC(3.0)/RC(40.0),RC(9.0)/RC(40.0),0,0,0,0,0}, 231 {RC(44.0)/RC(45.0),RC(-56.0)/RC(15.0),RC(32.0)/RC(9.0),0,0,0,0}, 232 {RC(19372.0)/RC(6561.0),RC(-25360.0)/RC(2187.0),RC(64448.0)/RC(6561.0),RC(-212.0)/RC(729.0),0,0,0}, 233 {RC(9017.0)/RC(3168.0),RC(-355.0)/RC(33.0),RC(46732.0)/RC(5247.0),RC(49.0)/RC(176.0),RC(-5103.0)/RC(18656.0),0,0}, 234 {RC(35.0)/RC(384.0),0,RC(500.0)/RC(1113.0),RC(125.0)/RC(192.0),RC(-2187.0)/RC(6784.0),RC(11.0)/RC(84.0),0}}, 235 b[7] = {RC(35.0)/RC(384.0),0,RC(500.0)/RC(1113.0),RC(125.0)/RC(192.0),RC(-2187.0)/RC(6784.0),RC(11.0)/RC(84.0),0}, 236 bembed[7] = {RC(5179.0)/RC(57600.0),0,RC(7571.0)/RC(16695.0),RC(393.0)/RC(640.0),RC(-92097.0)/RC(339200.0),RC(187.0)/RC(2100.0),RC(1.0)/RC(40.0)}; 237 ierr = TSRKRegister(TSRK5DP,5,7,&A[0][0],b,NULL,bembed,0,NULL);CHKERRQ(ierr); 238 } 239 { 240 const PetscReal 241 A[8][8] = {{0,0,0,0,0,0,0,0}, 242 {RC(1.0)/RC(6.0),0,0,0,0,0,0,0}, 243 {RC(2.0)/RC(27.0),RC(4.0)/RC(27.0),0,0,0,0,0,0}, 244 {RC(183.0)/RC(1372.0),RC(-162.0)/RC(343.0),RC(1053.0)/RC(1372.0),0,0,0,0,0}, 245 {RC(68.0)/RC(297.0),RC(-4.0)/RC(11.0),RC(42.0)/RC(143.0),RC(1960.0)/RC(3861.0),0,0,0,0}, 246 {RC(597.0)/RC(22528.0),RC(81.0)/RC(352.0),RC(63099.0)/RC(585728.0),RC(58653.0)/RC(366080.0),RC(4617.0)/RC(20480.0),0,0,0}, 247 {RC(174197.0)/RC(959244.0),RC(-30942.0)/RC(79937.0),RC(8152137.0)/RC(19744439.0),RC(666106.0)/RC(1039181.0),RC(-29421.0)/RC(29068.0),RC(482048.0)/RC(414219.0),0,0}, 248 {RC(587.0)/RC(8064.0),0,RC(4440339.0)/RC(15491840.0),RC(24353.0)/RC(124800.0),RC(387.0)/RC(44800.0),RC(2152.0)/RC(5985.0),RC(7267.0)/RC(94080.0),0}}, 249 b[8] = {RC(587.0)/RC(8064.0),0,RC(4440339.0)/RC(15491840.0),RC(24353.0)/RC(124800.0),RC(387.0)/RC(44800.0),RC(2152.0)/RC(5985.0),RC(7267.0)/RC(94080.0),0}, 250 bembed[8] = {RC(2479.0)/RC(34992.0),0,RC(123.0)/RC(416.0),RC(612941.0)/RC(3411720.0),RC(43.0)/RC(1440.0),RC(2272.0)/RC(6561.0),RC(79937.0)/RC(1113912.0),RC(3293.0)/RC(556956.0)}; 251 ierr = TSRKRegister(TSRK5BS,5,8,&A[0][0],b,NULL,bembed,0,NULL);CHKERRQ(ierr); 252 } 253 #undef RC 254 PetscFunctionReturn(0); 255 } 256 257 /*@C 258 TSRKRegisterDestroy - Frees the list of schemes that were registered by TSRKRegister(). 259 260 Not Collective 261 262 Level: advanced 263 264 .keywords: TSRK, register, destroy 265 .seealso: TSRKRegister(), TSRKRegisterAll() 266 @*/ 267 PetscErrorCode TSRKRegisterDestroy(void) 268 { 269 PetscErrorCode ierr; 270 RKTableauLink link; 271 272 PetscFunctionBegin; 273 while ((link = RKTableauList)) { 274 RKTableau t = &link->tab; 275 RKTableauList = link->next; 276 ierr = PetscFree3(t->A,t->b,t->c); CHKERRQ(ierr); 277 ierr = PetscFree (t->bembed); CHKERRQ(ierr); 278 ierr = PetscFree (t->binterp); CHKERRQ(ierr); 279 ierr = PetscFree (t->name); CHKERRQ(ierr); 280 ierr = PetscFree (link); CHKERRQ(ierr); 281 } 282 TSRKRegisterAllCalled = PETSC_FALSE; 283 PetscFunctionReturn(0); 284 } 285 286 /*@C 287 TSRKInitializePackage - This function initializes everything in the TSRK package. It is called 288 from TSInitializePackage(). 289 290 Level: developer 291 292 .keywords: TS, TSRK, initialize, package 293 .seealso: PetscInitialize() 294 @*/ 295 PetscErrorCode TSRKInitializePackage(void) 296 { 297 PetscErrorCode ierr; 298 299 PetscFunctionBegin; 300 if (TSRKPackageInitialized) PetscFunctionReturn(0); 301 TSRKPackageInitialized = PETSC_TRUE; 302 ierr = TSRKRegisterAll();CHKERRQ(ierr); 303 ierr = PetscRegisterFinalize(TSRKFinalizePackage);CHKERRQ(ierr); 304 PetscFunctionReturn(0); 305 } 306 307 /*@C 308 TSRKFinalizePackage - This function destroys everything in the TSRK package. It is 309 called from PetscFinalize(). 310 311 Level: developer 312 313 .keywords: Petsc, destroy, package 314 .seealso: PetscFinalize() 315 @*/ 316 PetscErrorCode TSRKFinalizePackage(void) 317 { 318 PetscErrorCode ierr; 319 320 PetscFunctionBegin; 321 TSRKPackageInitialized = PETSC_FALSE; 322 ierr = TSRKRegisterDestroy();CHKERRQ(ierr); 323 PetscFunctionReturn(0); 324 } 325 326 /*@C 327 TSRKRegister - register an RK scheme by providing the entries in the Butcher tableau and optionally embedded approximations and interpolation 328 329 Not Collective, but the same schemes should be registered on all processes on which they will be used 330 331 Input Parameters: 332 + name - identifier for method 333 . order - approximation order of method 334 . s - number of stages, this is the dimension of the matrices below 335 . A - stage coefficients (dimension s*s, row-major) 336 . b - step completion table (dimension s; NULL to use last row of A) 337 . c - abscissa (dimension s; NULL to use row sums of A) 338 . bembed - completion table for embedded method (dimension s; NULL if not available) 339 . p - Order of the interpolation scheme, equal to the number of columns of binterp 340 - binterp - Coefficients of the interpolation formula (dimension s*p; NULL to reuse b with p=1) 341 342 Notes: 343 Several RK methods are provided, this function is only needed to create new methods. 344 345 Level: advanced 346 347 .keywords: TS, register 348 349 .seealso: TSRK 350 @*/ 351 PetscErrorCode TSRKRegister(TSRKType name,PetscInt order,PetscInt s, 352 const PetscReal A[],const PetscReal b[],const PetscReal c[], 353 const PetscReal bembed[],PetscInt p,const PetscReal binterp[]) 354 { 355 PetscErrorCode ierr; 356 RKTableauLink link; 357 RKTableau t; 358 PetscInt i,j; 359 360 PetscFunctionBegin; 361 PetscValidCharPointer(name,1); 362 PetscValidRealPointer(A,4); 363 if (b) PetscValidRealPointer(b,5); 364 if (c) PetscValidRealPointer(c,6); 365 if (bembed) PetscValidRealPointer(bembed,7); 366 if (binterp || p > 1) PetscValidRealPointer(binterp,9); 367 368 ierr = TSRKInitializePackage();CHKERRQ(ierr); 369 ierr = PetscNew(&link);CHKERRQ(ierr); 370 t = &link->tab; 371 372 ierr = PetscStrallocpy(name,&t->name);CHKERRQ(ierr); 373 t->order = order; 374 t->s = s; 375 ierr = PetscMalloc3(s*s,&t->A,s,&t->b,s,&t->c);CHKERRQ(ierr); 376 ierr = PetscMemcpy(t->A,A,s*s*sizeof(A[0]));CHKERRQ(ierr); 377 if (b) { ierr = PetscMemcpy(t->b,b,s*sizeof(b[0]));CHKERRQ(ierr); } 378 else for (i=0; i<s; i++) t->b[i] = A[(s-1)*s+i]; 379 if (c) { ierr = PetscMemcpy(t->c,c,s*sizeof(c[0]));CHKERRQ(ierr); } 380 else for (i=0; i<s; i++) for (j=0,t->c[i]=0; j<s; j++) t->c[i] += A[i*s+j]; 381 t->FSAL = PETSC_TRUE; 382 for (i=0; i<s; i++) if (t->A[(s-1)*s+i] != t->b[i]) t->FSAL = PETSC_FALSE; 383 384 if (bembed) { 385 ierr = PetscMalloc1(s,&t->bembed);CHKERRQ(ierr); 386 ierr = PetscMemcpy(t->bembed,bembed,s*sizeof(bembed[0]));CHKERRQ(ierr); 387 } 388 389 if (!binterp) { p = 1; binterp = t->b; } 390 t->p = p; 391 ierr = PetscMalloc1(s*p,&t->binterp);CHKERRQ(ierr); 392 ierr = PetscMemcpy(t->binterp,binterp,s*p*sizeof(binterp[0]));CHKERRQ(ierr); 393 394 link->next = RKTableauList; 395 RKTableauList = link; 396 PetscFunctionReturn(0); 397 } 398 399 /* 400 The step completion formula is 401 402 x1 = x0 + h b^T YdotRHS 403 404 This function can be called before or after ts->vec_sol has been updated. 405 Suppose we have a completion formula (b) and an embedded formula (be) of different order. 406 We can write 407 408 x1e = x0 + h be^T YdotRHS 409 = x1 - h b^T YdotRHS + h be^T YdotRHS 410 = x1 + h (be - b)^T YdotRHS 411 412 so we can evaluate the method with different order even after the step has been optimistically completed. 413 */ 414 static PetscErrorCode TSEvaluateStep_RK(TS ts,PetscInt order,Vec X,PetscBool *done) 415 { 416 TS_RK *rk = (TS_RK*)ts->data; 417 RKTableau tab = rk->tableau; 418 PetscScalar *w = rk->work; 419 PetscReal h; 420 PetscInt s = tab->s,j; 421 PetscErrorCode ierr; 422 423 PetscFunctionBegin; 424 switch (rk->status) { 425 case TS_STEP_INCOMPLETE: 426 case TS_STEP_PENDING: 427 h = ts->time_step; break; 428 case TS_STEP_COMPLETE: 429 h = ts->ptime - ts->ptime_prev; break; 430 default: SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_PLIB,"Invalid TSStepStatus"); 431 } 432 if (order == tab->order) { 433 if (rk->status == TS_STEP_INCOMPLETE) { 434 ierr = VecCopy(ts->vec_sol,X);CHKERRQ(ierr); 435 for (j=0; j<s; j++) w[j] = h*tab->b[j]; 436 ierr = VecMAXPY(X,s,w,rk->YdotRHS);CHKERRQ(ierr); 437 } else {ierr = VecCopy(ts->vec_sol,X);CHKERRQ(ierr);} 438 PetscFunctionReturn(0); 439 } else if (order == tab->order-1) { 440 if (!tab->bembed) goto unavailable; 441 if (rk->status == TS_STEP_INCOMPLETE) { /* Complete with the embedded method (be) */ 442 ierr = VecCopy(ts->vec_sol,X);CHKERRQ(ierr); 443 for (j=0; j<s; j++) w[j] = h*tab->bembed[j]; 444 ierr = VecMAXPY(X,s,w,rk->YdotRHS);CHKERRQ(ierr); 445 } else { /* Rollback and re-complete using (be-b) */ 446 ierr = VecCopy(ts->vec_sol,X);CHKERRQ(ierr); 447 for (j=0; j<s; j++) w[j] = h*(tab->bembed[j] - tab->b[j]); 448 ierr = VecMAXPY(X,s,w,rk->YdotRHS);CHKERRQ(ierr); 449 } 450 if (done) *done = PETSC_TRUE; 451 PetscFunctionReturn(0); 452 } 453 unavailable: 454 if (done) *done = PETSC_FALSE; 455 else SETERRQ3(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"RK '%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); 456 PetscFunctionReturn(0); 457 } 458 459 static PetscErrorCode TSForwardCostIntegral_RK(TS ts) 460 { 461 TS_RK *rk = (TS_RK*)ts->data; 462 RKTableau tab = rk->tableau; 463 const PetscInt s = tab->s; 464 const PetscReal *b = tab->b,*c = tab->c; 465 Vec *Y = rk->Y; 466 PetscInt i; 467 PetscErrorCode ierr; 468 469 PetscFunctionBegin; 470 /* backup cost integral */ 471 ierr = VecCopy(ts->vec_costintegral,rk->VecCostIntegral0);CHKERRQ(ierr); 472 for (i=s-1; i>=0; i--) { 473 /* Evolve ts->vec_costintegral to compute integrals */ 474 ierr = TSComputeCostIntegrand(ts,rk->ptime+rk->time_step*c[i],Y[i],ts->vec_costintegrand);CHKERRQ(ierr); 475 ierr = VecAXPY(ts->vec_costintegral,rk->time_step*b[i],ts->vec_costintegrand);CHKERRQ(ierr); 476 } 477 PetscFunctionReturn(0); 478 } 479 480 static PetscErrorCode TSAdjointCostIntegral_RK(TS ts) 481 { 482 TS_RK *rk = (TS_RK*)ts->data; 483 RKTableau tab = rk->tableau; 484 const PetscInt s = tab->s; 485 const PetscReal *b = tab->b,*c = tab->c; 486 Vec *Y = rk->Y; 487 PetscInt i; 488 PetscErrorCode ierr; 489 490 PetscFunctionBegin; 491 for (i=s-1; i>=0; i--) { 492 /* Evolve ts->vec_costintegral to compute integrals */ 493 ierr = TSComputeCostIntegrand(ts,ts->ptime+ts->time_step*(1.0-c[i]),Y[i],ts->vec_costintegrand);CHKERRQ(ierr); 494 ierr = VecAXPY(ts->vec_costintegral,-ts->time_step*b[i],ts->vec_costintegrand);CHKERRQ(ierr); 495 } 496 PetscFunctionReturn(0); 497 } 498 499 static PetscErrorCode TSRollBack_RK(TS ts) 500 { 501 TS_RK *rk = (TS_RK*)ts->data; 502 RKTableau tab = rk->tableau; 503 const PetscInt s = tab->s; 504 const PetscReal *b = tab->b; 505 PetscScalar *w = rk->work; 506 Vec *YdotRHS = rk->YdotRHS; 507 PetscInt j; 508 PetscReal h; 509 PetscErrorCode ierr; 510 511 PetscFunctionBegin; 512 switch (rk->status) { 513 case TS_STEP_INCOMPLETE: 514 case TS_STEP_PENDING: 515 h = ts->time_step; break; 516 case TS_STEP_COMPLETE: 517 h = ts->ptime - ts->ptime_prev; break; 518 default: SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_PLIB,"Invalid TSStepStatus"); 519 } 520 for (j=0; j<s; j++) w[j] = -h*b[j]; 521 ierr = VecMAXPY(ts->vec_sol,s,w,YdotRHS);CHKERRQ(ierr); 522 PetscFunctionReturn(0); 523 } 524 525 static PetscErrorCode TSStep_RK(TS ts) 526 { 527 TS_RK *rk = (TS_RK*)ts->data; 528 RKTableau tab = rk->tableau; 529 const PetscInt s = tab->s; 530 const PetscReal *A = tab->A,*c = tab->c; 531 PetscScalar *w = rk->work; 532 Vec *Y = rk->Y,*YdotRHS = rk->YdotRHS; 533 PetscBool FSAL = tab->FSAL; 534 TSAdapt adapt; 535 PetscInt i,j; 536 PetscInt rejections = 0; 537 PetscBool stageok,accept = PETSC_TRUE; 538 PetscReal next_time_step = ts->time_step; 539 PetscErrorCode ierr; 540 541 PetscFunctionBegin; 542 if (ts->steprollback || ts->steprestart) FSAL = PETSC_FALSE; 543 if (FSAL) { ierr = VecCopy(YdotRHS[s-1],YdotRHS[0]);CHKERRQ(ierr); } 544 545 rk->status = TS_STEP_INCOMPLETE; 546 while (!ts->reason && rk->status != TS_STEP_COMPLETE) { 547 PetscReal t = ts->ptime; 548 PetscReal h = ts->time_step; 549 for (i=0; i<s; i++) { 550 rk->stage_time = t + h*c[i]; 551 ierr = TSPreStage(ts,rk->stage_time); CHKERRQ(ierr); 552 ierr = VecCopy(ts->vec_sol,Y[i]);CHKERRQ(ierr); 553 for (j=0; j<i; j++) w[j] = h*A[i*s+j]; 554 ierr = VecMAXPY(Y[i],i,w,YdotRHS);CHKERRQ(ierr); 555 ierr = TSPostStage(ts,rk->stage_time,i,Y); CHKERRQ(ierr); 556 ierr = TSGetAdapt(ts,&adapt);CHKERRQ(ierr); 557 ierr = TSAdaptCheckStage(adapt,ts,rk->stage_time,Y[i],&stageok);CHKERRQ(ierr); 558 if (!stageok) goto reject_step; 559 if (FSAL && !i) continue; 560 ierr = TSComputeRHSFunction(ts,t+h*c[i],Y[i],YdotRHS[i]);CHKERRQ(ierr); 561 } 562 563 rk->status = TS_STEP_INCOMPLETE; 564 ierr = TSEvaluateStep(ts,tab->order,ts->vec_sol,NULL);CHKERRQ(ierr); 565 rk->status = TS_STEP_PENDING; 566 ierr = TSGetAdapt(ts,&adapt);CHKERRQ(ierr); 567 ierr = TSAdaptCandidatesClear(adapt);CHKERRQ(ierr); 568 ierr = TSAdaptCandidateAdd(adapt,tab->name,tab->order,1,tab->ccfl,(PetscReal)tab->s,PETSC_TRUE);CHKERRQ(ierr); 569 ierr = TSAdaptChoose(adapt,ts,ts->time_step,NULL,&next_time_step,&accept);CHKERRQ(ierr); 570 rk->status = accept ? TS_STEP_COMPLETE : TS_STEP_INCOMPLETE; 571 if (!accept) { /* Roll back the current step */ 572 ierr = TSRollBack_RK(ts);CHKERRQ(ierr); 573 ts->time_step = next_time_step; 574 goto reject_step; 575 } 576 577 if (ts->costintegralfwd) { /* Save the info for the later use in cost integral evaluation*/ 578 rk->ptime = ts->ptime; 579 rk->time_step = ts->time_step; 580 } 581 582 ts->ptime += ts->time_step; 583 ts->time_step = next_time_step; 584 break; 585 586 reject_step: 587 ts->reject++; accept = PETSC_FALSE; 588 if (!ts->reason && ++rejections > ts->max_reject && ts->max_reject >= 0) { 589 ts->reason = TS_DIVERGED_STEP_REJECTED; 590 ierr = PetscInfo2(ts,"Step=%D, step rejections %D greater than current TS allowed, stopping solve\n",ts->steps,rejections);CHKERRQ(ierr); 591 } 592 } 593 PetscFunctionReturn(0); 594 } 595 596 static PetscErrorCode TSAdjointSetUp_RK(TS ts) 597 { 598 TS_RK *rk = (TS_RK*)ts->data; 599 RKTableau tab = rk->tableau; 600 PetscInt s = tab->s; 601 PetscErrorCode ierr; 602 603 PetscFunctionBegin; 604 if (ts->adjointsetupcalled++) PetscFunctionReturn(0); 605 ierr = VecDuplicateVecs(ts->vecs_sensi[0],s*ts->numcost,&rk->VecDeltaLam);CHKERRQ(ierr); 606 if(ts->vecs_sensip) { 607 ierr = VecDuplicateVecs(ts->vecs_sensip[0],s*ts->numcost,&rk->VecDeltaMu);CHKERRQ(ierr); 608 } 609 PetscFunctionReturn(0); 610 } 611 612 static PetscErrorCode TSAdjointStep_RK(TS ts) 613 { 614 TS_RK *rk = (TS_RK*)ts->data; 615 RKTableau tab = rk->tableau; 616 const PetscInt s = tab->s; 617 const PetscReal *A = tab->A,*b = tab->b,*c = tab->c; 618 PetscScalar *w = rk->work; 619 Vec *Y = rk->Y,*VecDeltaLam = rk->VecDeltaLam,*VecDeltaMu = rk->VecDeltaMu; 620 PetscInt i,j,nadj; 621 PetscReal t = ts->ptime; 622 PetscErrorCode ierr; 623 PetscReal h = ts->time_step; 624 625 PetscFunctionBegin; 626 rk->status = TS_STEP_INCOMPLETE; 627 for (i=s-1; i>=0; i--) { 628 Mat J; 629 PetscReal stage_time = t + h*(1.0-c[i]); 630 PetscBool zero = PETSC_FALSE; 631 632 ierr = TSGetRHSJacobian(ts,&J,NULL,NULL,NULL);CHKERRQ(ierr); 633 ierr = TSComputeRHSJacobian(ts,stage_time,Y[i],J,J);CHKERRQ(ierr); 634 if (ts->vec_costintegral) { 635 ierr = TSAdjointComputeDRDYFunction(ts,stage_time,Y[i],ts->vecs_drdy);CHKERRQ(ierr); 636 } 637 /* Stage values of mu */ 638 if (ts->vecs_sensip) { 639 ierr = TSAdjointComputeRHSJacobian(ts,stage_time,Y[i],ts->Jacp);CHKERRQ(ierr); 640 if (ts->vec_costintegral) { 641 ierr = TSAdjointComputeDRDPFunction(ts,stage_time,Y[i],ts->vecs_drdp);CHKERRQ(ierr); 642 } 643 } 644 645 if (b[i] == 0 && i == s-1) zero = PETSC_TRUE; 646 for (nadj=0; nadj<ts->numcost; nadj++) { 647 DM dm; 648 Vec VecSensiTemp; 649 650 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 651 ierr = DMGetGlobalVector(dm,&VecSensiTemp);CHKERRQ(ierr); 652 /* Stage values of lambda */ 653 if (!zero) { 654 ierr = VecCopy(ts->vecs_sensi[nadj],VecSensiTemp);CHKERRQ(ierr); 655 ierr = VecScale(VecSensiTemp,-h*b[i]);CHKERRQ(ierr); 656 for (j=i+1; j<s; j++) w[j-i-1] = -h*A[j*s+i]; 657 ierr = VecMAXPY(VecSensiTemp,s-i-1,w,&VecDeltaLam[nadj*s+i+1]);CHKERRQ(ierr); 658 ierr = MatMultTranspose(J,VecSensiTemp,VecDeltaLam[nadj*s+i]);CHKERRQ(ierr); 659 } else { 660 ierr = VecSet(VecDeltaLam[nadj*s+i],0);CHKERRQ(ierr); 661 } 662 if (ts->vec_costintegral) { 663 ierr = VecAXPY(VecDeltaLam[nadj*s+i],-h*b[i],ts->vecs_drdy[nadj]);CHKERRQ(ierr); 664 } 665 666 /* Stage values of mu */ 667 if (ts->vecs_sensip) { 668 if (!zero) { 669 ierr = MatMultTranspose(ts->Jacp,VecSensiTemp,VecDeltaMu[nadj*s+i]);CHKERRQ(ierr); 670 } else { 671 ierr = VecSet(VecDeltaMu[nadj*s+i],0);CHKERRQ(ierr); 672 } 673 if (ts->vec_costintegral) { 674 ierr = VecAXPY(VecDeltaMu[nadj*s+i],-h*b[i],ts->vecs_drdp[nadj]);CHKERRQ(ierr); 675 } 676 } 677 ierr = DMRestoreGlobalVector(dm,&VecSensiTemp);CHKERRQ(ierr); 678 } 679 } 680 681 for (j=0; j<s; j++) w[j] = 1.0; 682 for (nadj=0; nadj<ts->numcost; nadj++) { 683 ierr = VecMAXPY(ts->vecs_sensi[nadj],s,w,&VecDeltaLam[nadj*s]);CHKERRQ(ierr); 684 if (ts->vecs_sensip) { 685 ierr = VecMAXPY(ts->vecs_sensip[nadj],s,w,&VecDeltaMu[nadj*s]);CHKERRQ(ierr); 686 } 687 } 688 rk->status = TS_STEP_COMPLETE; 689 PetscFunctionReturn(0); 690 } 691 692 static PetscErrorCode TSInterpolate_RK(TS ts,PetscReal itime,Vec X) 693 { 694 TS_RK *rk = (TS_RK*)ts->data; 695 PetscInt s = rk->tableau->s,p = rk->tableau->p,i,j; 696 PetscReal h; 697 PetscReal tt,t; 698 PetscScalar *b; 699 const PetscReal *B = rk->tableau->binterp; 700 PetscErrorCode ierr; 701 702 PetscFunctionBegin; 703 if (!B) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSRK %s does not have an interpolation formula",rk->tableau->name); 704 705 switch (rk->status) { 706 case TS_STEP_INCOMPLETE: 707 case TS_STEP_PENDING: 708 h = ts->time_step; 709 t = (itime - ts->ptime)/h; 710 break; 711 case TS_STEP_COMPLETE: 712 h = ts->ptime - ts->ptime_prev; 713 t = (itime - ts->ptime)/h + 1; /* In the interval [0,1] */ 714 break; 715 default: SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_PLIB,"Invalid TSStepStatus"); 716 } 717 ierr = PetscMalloc1(s,&b);CHKERRQ(ierr); 718 for (i=0; i<s; i++) b[i] = 0; 719 for (j=0,tt=t; j<p; j++,tt*=t) { 720 for (i=0; i<s; i++) { 721 b[i] += h * B[i*p+j] * tt; 722 } 723 } 724 725 ierr = VecCopy(rk->Y[0],X);CHKERRQ(ierr); 726 ierr = VecMAXPY(X,s,b,rk->YdotRHS);CHKERRQ(ierr); 727 728 ierr = PetscFree(b);CHKERRQ(ierr); 729 PetscFunctionReturn(0); 730 } 731 732 /*------------------------------------------------------------*/ 733 734 static PetscErrorCode TSRKTableauReset(TS ts) 735 { 736 TS_RK *rk = (TS_RK*)ts->data; 737 RKTableau tab = rk->tableau; 738 PetscErrorCode ierr; 739 740 PetscFunctionBegin; 741 if (!tab) PetscFunctionReturn(0); 742 ierr = PetscFree(rk->work);CHKERRQ(ierr); 743 ierr = VecDestroyVecs(tab->s,&rk->Y);CHKERRQ(ierr); 744 ierr = VecDestroyVecs(tab->s,&rk->YdotRHS);CHKERRQ(ierr); 745 ierr = VecDestroyVecs(tab->s*ts->numcost,&rk->VecDeltaLam);CHKERRQ(ierr); 746 ierr = VecDestroyVecs(tab->s*ts->numcost,&rk->VecDeltaMu);CHKERRQ(ierr); 747 PetscFunctionReturn(0); 748 } 749 750 static PetscErrorCode TSReset_RK(TS ts) 751 { 752 TS_RK *rk = (TS_RK*)ts->data; 753 PetscErrorCode ierr; 754 755 PetscFunctionBegin; 756 ierr = TSRKTableauReset(ts);CHKERRQ(ierr); 757 ierr = VecDestroy(&rk->VecCostIntegral0);CHKERRQ(ierr); 758 PetscFunctionReturn(0); 759 } 760 761 static PetscErrorCode DMCoarsenHook_TSRK(DM fine,DM coarse,void *ctx) 762 { 763 PetscFunctionBegin; 764 PetscFunctionReturn(0); 765 } 766 767 static PetscErrorCode DMRestrictHook_TSRK(DM fine,Mat restrct,Vec rscale,Mat inject,DM coarse,void *ctx) 768 { 769 PetscFunctionBegin; 770 PetscFunctionReturn(0); 771 } 772 773 774 static PetscErrorCode DMSubDomainHook_TSRK(DM dm,DM subdm,void *ctx) 775 { 776 PetscFunctionBegin; 777 PetscFunctionReturn(0); 778 } 779 780 static PetscErrorCode DMSubDomainRestrictHook_TSRK(DM dm,VecScatter gscat,VecScatter lscat,DM subdm,void *ctx) 781 { 782 783 PetscFunctionBegin; 784 PetscFunctionReturn(0); 785 } 786 /* 787 static PetscErrorCode RKSetAdjCoe(RKTableau tab) 788 { 789 PetscReal *A,*b; 790 PetscInt s,i,j; 791 PetscErrorCode ierr; 792 793 PetscFunctionBegin; 794 s = tab->s; 795 ierr = PetscMalloc2(s*s,&A,s,&b);CHKERRQ(ierr); 796 797 for (i=0; i<s; i++) 798 for (j=0; j<s; j++) { 799 A[i*s+j] = (tab->b[s-1-i]==0) ? 0: -tab->A[s-1-i+(s-1-j)*s] * tab->b[s-1-j] / tab->b[s-1-i]; 800 ierr = PetscPrintf(PETSC_COMM_WORLD,"Coefficients: A[%D][%D]=%.6f\n",i,j,A[i*s+j]);CHKERRQ(ierr); 801 } 802 803 for (i=0; i<s; i++) b[i] = (tab->b[s-1-i]==0)? 0: -tab->b[s-1-i]; 804 805 ierr = PetscMemcpy(tab->A,A,s*s*sizeof(A[0]));CHKERRQ(ierr); 806 ierr = PetscMemcpy(tab->b,b,s*sizeof(b[0]));CHKERRQ(ierr); 807 ierr = PetscFree2(A,b);CHKERRQ(ierr); 808 PetscFunctionReturn(0); 809 } 810 */ 811 812 static PetscErrorCode TSRKTableauSetUp(TS ts) 813 { 814 TS_RK *rk = (TS_RK*)ts->data; 815 RKTableau tab = rk->tableau; 816 PetscErrorCode ierr; 817 818 PetscFunctionBegin; 819 ierr = PetscMalloc1(tab->s,&rk->work);CHKERRQ(ierr); 820 ierr = VecDuplicateVecs(ts->vec_sol,tab->s,&rk->Y);CHKERRQ(ierr); 821 ierr = VecDuplicateVecs(ts->vec_sol,tab->s,&rk->YdotRHS);CHKERRQ(ierr); 822 PetscFunctionReturn(0); 823 } 824 825 826 static PetscErrorCode TSSetUp_RK(TS ts) 827 { 828 TS_RK *rk = (TS_RK*)ts->data; 829 PetscErrorCode ierr; 830 DM dm; 831 832 PetscFunctionBegin; 833 ierr = TSCheckImplicitTerm(ts);CHKERRQ(ierr); 834 ierr = TSRKTableauSetUp(ts);CHKERRQ(ierr); 835 if (!rk->VecCostIntegral0 && ts->vec_costintegral && ts->costintegralfwd) { /* back up cost integral */ 836 ierr = VecDuplicate(ts->vec_costintegral,&rk->VecCostIntegral0);CHKERRQ(ierr); 837 } 838 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 839 ierr = DMCoarsenHookAdd(dm,DMCoarsenHook_TSRK,DMRestrictHook_TSRK,ts);CHKERRQ(ierr); 840 ierr = DMSubDomainHookAdd(dm,DMSubDomainHook_TSRK,DMSubDomainRestrictHook_TSRK,ts);CHKERRQ(ierr); 841 PetscFunctionReturn(0); 842 } 843 844 845 /*------------------------------------------------------------*/ 846 847 static PetscErrorCode TSSetFromOptions_RK(PetscOptionItems *PetscOptionsObject,TS ts) 848 { 849 TS_RK *rk = (TS_RK*)ts->data; 850 PetscErrorCode ierr; 851 852 PetscFunctionBegin; 853 ierr = PetscOptionsHead(PetscOptionsObject,"RK ODE solver options");CHKERRQ(ierr); 854 { 855 RKTableauLink link; 856 PetscInt count,choice; 857 PetscBool flg; 858 const char **namelist; 859 for (link=RKTableauList,count=0; link; link=link->next,count++) ; 860 ierr = PetscMalloc1(count,(char***)&namelist);CHKERRQ(ierr); 861 for (link=RKTableauList,count=0; link; link=link->next,count++) namelist[count] = link->tab.name; 862 ierr = PetscOptionsEList("-ts_rk_type","Family of RK method","TSRKSetType",(const char*const*)namelist,count,rk->tableau->name,&choice,&flg);CHKERRQ(ierr); 863 if (flg) {ierr = TSRKSetType(ts,namelist[choice]);CHKERRQ(ierr);} 864 ierr = PetscFree(namelist);CHKERRQ(ierr); 865 } 866 ierr = PetscOptionsTail();CHKERRQ(ierr); 867 PetscFunctionReturn(0); 868 } 869 870 static PetscErrorCode TSView_RK(TS ts,PetscViewer viewer) 871 { 872 TS_RK *rk = (TS_RK*)ts->data; 873 PetscBool iascii; 874 PetscErrorCode ierr; 875 876 PetscFunctionBegin; 877 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 878 if (iascii) { 879 RKTableau tab = rk->tableau; 880 TSRKType rktype; 881 char buf[512]; 882 ierr = TSRKGetType(ts,&rktype);CHKERRQ(ierr); 883 ierr = PetscViewerASCIIPrintf(viewer," RK type %s\n",rktype);CHKERRQ(ierr); 884 ierr = PetscViewerASCIIPrintf(viewer," Order: %D\n",tab->order);CHKERRQ(ierr); 885 ierr = PetscViewerASCIIPrintf(viewer," FSAL property: %s\n",tab->FSAL ? "yes" : "no");CHKERRQ(ierr); 886 ierr = PetscFormatRealArray(buf,sizeof(buf),"% 8.6f",tab->s,tab->c);CHKERRQ(ierr); 887 ierr = PetscViewerASCIIPrintf(viewer," Abscissa c = %s\n",buf);CHKERRQ(ierr); 888 } 889 PetscFunctionReturn(0); 890 } 891 892 static PetscErrorCode TSLoad_RK(TS ts,PetscViewer viewer) 893 { 894 PetscErrorCode ierr; 895 TSAdapt adapt; 896 897 PetscFunctionBegin; 898 ierr = TSGetAdapt(ts,&adapt);CHKERRQ(ierr); 899 ierr = TSAdaptLoad(adapt,viewer);CHKERRQ(ierr); 900 PetscFunctionReturn(0); 901 } 902 903 /*@C 904 TSRKSetType - Set the type of RK scheme 905 906 Logically collective 907 908 Input Parameter: 909 + ts - timestepping context 910 - rktype - type of RK-scheme 911 912 Options Database: 913 . -ts_rk_type - <1fe,2a,3,3bs,4,5f,5dp,5bs> 914 915 Level: intermediate 916 917 .seealso: TSRKGetType(), TSRK, TSRKType, TSRK1FE, TSRK2A, TSRK3, TSRK3BS, TSRK4, TSRK5F, TSRK5DP, TSRK5BS 918 @*/ 919 PetscErrorCode TSRKSetType(TS ts,TSRKType rktype) 920 { 921 PetscErrorCode ierr; 922 923 PetscFunctionBegin; 924 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 925 PetscValidCharPointer(rktype,2); 926 ierr = PetscTryMethod(ts,"TSRKSetType_C",(TS,TSRKType),(ts,rktype));CHKERRQ(ierr); 927 PetscFunctionReturn(0); 928 } 929 930 /*@C 931 TSRKGetType - Get the type of RK scheme 932 933 Logically collective 934 935 Input Parameter: 936 . ts - timestepping context 937 938 Output Parameter: 939 . rktype - type of RK-scheme 940 941 Level: intermediate 942 943 .seealso: TSRKGetType() 944 @*/ 945 PetscErrorCode TSRKGetType(TS ts,TSRKType *rktype) 946 { 947 PetscErrorCode ierr; 948 949 PetscFunctionBegin; 950 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 951 ierr = PetscUseMethod(ts,"TSRKGetType_C",(TS,TSRKType*),(ts,rktype));CHKERRQ(ierr); 952 PetscFunctionReturn(0); 953 } 954 955 static PetscErrorCode TSRKGetType_RK(TS ts,TSRKType *rktype) 956 { 957 TS_RK *rk = (TS_RK*)ts->data; 958 959 PetscFunctionBegin; 960 *rktype = rk->tableau->name; 961 PetscFunctionReturn(0); 962 } 963 static PetscErrorCode TSRKSetType_RK(TS ts,TSRKType rktype) 964 { 965 TS_RK *rk = (TS_RK*)ts->data; 966 PetscErrorCode ierr; 967 PetscBool match; 968 RKTableauLink link; 969 970 PetscFunctionBegin; 971 if (rk->tableau) { 972 ierr = PetscStrcmp(rk->tableau->name,rktype,&match);CHKERRQ(ierr); 973 if (match) PetscFunctionReturn(0); 974 } 975 for (link = RKTableauList; link; link=link->next) { 976 ierr = PetscStrcmp(link->tab.name,rktype,&match);CHKERRQ(ierr); 977 if (match) { 978 if (ts->setupcalled) {ierr = TSRKTableauReset(ts);CHKERRQ(ierr);} 979 rk->tableau = &link->tab; 980 if (ts->setupcalled) {ierr = TSRKTableauSetUp(ts);CHKERRQ(ierr);} 981 ts->default_adapt_type = rk->tableau->bembed ? TSADAPTBASIC : TSADAPTNONE; 982 PetscFunctionReturn(0); 983 } 984 } 985 SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_UNKNOWN_TYPE,"Could not find '%s'",rktype); 986 PetscFunctionReturn(0); 987 } 988 989 static PetscErrorCode TSGetStages_RK(TS ts,PetscInt *ns,Vec **Y) 990 { 991 TS_RK *rk = (TS_RK*)ts->data; 992 993 PetscFunctionBegin; 994 if (ns) *ns = rk->tableau->s; 995 if (Y) *Y = rk->Y; 996 PetscFunctionReturn(0); 997 } 998 999 static PetscErrorCode TSDestroy_RK(TS ts) 1000 { 1001 PetscErrorCode ierr; 1002 1003 PetscFunctionBegin; 1004 ierr = TSReset_RK(ts);CHKERRQ(ierr); 1005 if (ts->dm) { 1006 ierr = DMCoarsenHookRemove(ts->dm,DMCoarsenHook_TSRK,DMRestrictHook_TSRK,ts);CHKERRQ(ierr); 1007 ierr = DMSubDomainHookRemove(ts->dm,DMSubDomainHook_TSRK,DMSubDomainRestrictHook_TSRK,ts);CHKERRQ(ierr); 1008 } 1009 ierr = PetscFree(ts->data);CHKERRQ(ierr); 1010 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSRKGetType_C",NULL);CHKERRQ(ierr); 1011 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSRKSetType_C",NULL);CHKERRQ(ierr); 1012 PetscFunctionReturn(0); 1013 } 1014 1015 /* ------------------------------------------------------------ */ 1016 /*MC 1017 TSRK - ODE and DAE solver using Runge-Kutta schemes 1018 1019 The user should provide the right hand side of the equation 1020 using TSSetRHSFunction(). 1021 1022 Notes: 1023 The default is TSRK3BS, it can be changed with TSRKSetType() or -ts_rk_type 1024 1025 Level: beginner 1026 1027 .seealso: TSCreate(), TS, TSSetType(), TSRKSetType(), TSRKGetType(), TSRKSetFullyImplicit(), TSRK2D, TTSRK2E, TSRK3, 1028 TSRK4, TSRK5, TSRKPRSSP2, TSRKBPR3, TSRKType, TSRKRegister() 1029 1030 M*/ 1031 PETSC_EXTERN PetscErrorCode TSCreate_RK(TS ts) 1032 { 1033 TS_RK *rk; 1034 PetscErrorCode ierr; 1035 1036 PetscFunctionBegin; 1037 ierr = TSRKInitializePackage();CHKERRQ(ierr); 1038 1039 ts->ops->reset = TSReset_RK; 1040 ts->ops->destroy = TSDestroy_RK; 1041 ts->ops->view = TSView_RK; 1042 ts->ops->load = TSLoad_RK; 1043 ts->ops->setup = TSSetUp_RK; 1044 ts->ops->adjointsetup = TSAdjointSetUp_RK; 1045 ts->ops->step = TSStep_RK; 1046 ts->ops->interpolate = TSInterpolate_RK; 1047 ts->ops->evaluatestep = TSEvaluateStep_RK; 1048 ts->ops->rollback = TSRollBack_RK; 1049 ts->ops->setfromoptions = TSSetFromOptions_RK; 1050 ts->ops->getstages = TSGetStages_RK; 1051 ts->ops->adjointstep = TSAdjointStep_RK; 1052 1053 ts->ops->adjointintegral = TSAdjointCostIntegral_RK; 1054 ts->ops->forwardintegral = TSForwardCostIntegral_RK; 1055 1056 ierr = PetscNewLog(ts,&rk);CHKERRQ(ierr); 1057 ts->data = (void*)rk; 1058 1059 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSRKGetType_C",TSRKGetType_RK);CHKERRQ(ierr); 1060 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSRKSetType_C",TSRKSetType_RK);CHKERRQ(ierr); 1061 1062 ierr = TSRKSetType(ts,TSRKDefault);CHKERRQ(ierr); 1063 PetscFunctionReturn(0); 1064 } 1065