1e4dd521cSBarry Smith /* 2474dd773SHong Zhang Code for time stepping with the Runge-Kutta method 3f68a32c8SEmil Constantinescu 4f68a32c8SEmil Constantinescu Notes: 5474dd773SHong Zhang The general system is written as 6474dd773SHong Zhang 7474dd773SHong Zhang Udot = F(t,U) 8474dd773SHong Zhang 9e4dd521cSBarry Smith */ 102c9cb062Sluzhanghpp 11af0996ceSBarry Smith #include <petsc/private/tsimpl.h> /*I "petscts.h" I*/ 12f68a32c8SEmil Constantinescu #include <petscdm.h> 13474dd773SHong Zhang #include <../src/ts/impls/explicit/rk/rk.h> 1421052c0cSHong Zhang #include <../src/ts/impls/explicit/rk/mrk.h> 15f68a32c8SEmil Constantinescu 16484bcdc7SDebojyoti Ghosh static TSRKType TSRKDefault = TSRK3BS; 17f68a32c8SEmil Constantinescu static PetscBool TSRKRegisterAllCalled; 18f68a32c8SEmil Constantinescu static PetscBool TSRKPackageInitialized; 19f68a32c8SEmil Constantinescu 20ab8985f5SHong Zhang static RKTableauLink RKTableauList; 21ab8985f5SHong Zhang 22f68a32c8SEmil Constantinescu /*MC 23287c2655SBarry Smith TSRK1FE - First order forward Euler scheme. 24262ff7bbSBarry Smith 25f68a32c8SEmil Constantinescu This method has one stage. 26f68a32c8SEmil Constantinescu 27bcf0153eSBarry Smith Options Database Key: 2867b8a455SSatish Balay . -ts_rk_type 1fe - use type 1fe 29287c2655SBarry Smith 30f68a32c8SEmil Constantinescu Level: advanced 31f68a32c8SEmil Constantinescu 321cc06b55SBarry Smith .seealso: [](ch_ts), `TSRK`, `TSRKType`, `TSRKSetType()` 33f68a32c8SEmil Constantinescu M*/ 34f68a32c8SEmil Constantinescu /*MC 35e7685601SHong Zhang TSRK2A - Second order RK scheme (Heun's method). 36f68a32c8SEmil Constantinescu 37f68a32c8SEmil Constantinescu This method has two stages. 38f68a32c8SEmil Constantinescu 39bcf0153eSBarry Smith Options Database Key: 4067b8a455SSatish Balay . -ts_rk_type 2a - use type 2a 41287c2655SBarry Smith 42f68a32c8SEmil Constantinescu Level: advanced 43f68a32c8SEmil Constantinescu 441cc06b55SBarry Smith .seealso: [](ch_ts), `TSRK`, `TSRKType`, `TSRKSetType()` 45f68a32c8SEmil Constantinescu M*/ 46f68a32c8SEmil Constantinescu /*MC 47e7685601SHong Zhang TSRK2B - Second order RK scheme (the midpoint method). 48e7685601SHong Zhang 49e7685601SHong Zhang This method has two stages. 50e7685601SHong Zhang 51bcf0153eSBarry Smith Options Database Key: 5267b8a455SSatish Balay . -ts_rk_type 2b - use type 2b 53e7685601SHong Zhang 54e7685601SHong Zhang Level: advanced 55e7685601SHong Zhang 561cc06b55SBarry Smith .seealso: [](ch_ts), `TSRK`, `TSRKType`, `TSRKSetType()` 57e7685601SHong Zhang M*/ 58e7685601SHong Zhang /*MC 59f68a32c8SEmil Constantinescu TSRK3 - Third order RK scheme. 60f68a32c8SEmil Constantinescu 61f68a32c8SEmil Constantinescu This method has three stages. 62f68a32c8SEmil Constantinescu 63bcf0153eSBarry Smith Options Database Key: 6467b8a455SSatish Balay . -ts_rk_type 3 - use type 3 65287c2655SBarry Smith 66f68a32c8SEmil Constantinescu Level: advanced 67f68a32c8SEmil Constantinescu 681cc06b55SBarry Smith .seealso: [](ch_ts), `TSRK`, `TSRKType`, `TSRKSetType()` 69f68a32c8SEmil Constantinescu M*/ 70f68a32c8SEmil Constantinescu /*MC 71*1d27aa22SBarry Smith TSRK3BS - Third order RK scheme of Bogacki-Shampine with 2nd order embedded method <https://doi.org/10.1016/0893-9659(89)90079-7> 722109b73fSDebojyoti Ghosh 73d1905564SLisandro Dalcin This method has four stages with the First Same As Last (FSAL) property. 742109b73fSDebojyoti Ghosh 75bcf0153eSBarry Smith Options Database Key: 7667b8a455SSatish Balay . -ts_rk_type 3bs - use type 3bs 77287c2655SBarry Smith 782109b73fSDebojyoti Ghosh Level: advanced 792109b73fSDebojyoti Ghosh 801cc06b55SBarry Smith .seealso: [](ch_ts), `TSRK`, `TSRKType`, `TSRKSetType()` 812109b73fSDebojyoti Ghosh M*/ 822109b73fSDebojyoti Ghosh /*MC 83f68a32c8SEmil Constantinescu TSRK4 - Fourth order RK scheme. 84f68a32c8SEmil Constantinescu 852e698f8bSDebojyoti Ghosh This is the classical Runge-Kutta method with four stages. 86f68a32c8SEmil Constantinescu 87bcf0153eSBarry Smith Options Database Key: 8867b8a455SSatish Balay . -ts_rk_type 4 - use type 4 89287c2655SBarry Smith 90f68a32c8SEmil Constantinescu Level: advanced 91f68a32c8SEmil Constantinescu 921cc06b55SBarry Smith .seealso: [](ch_ts), `TSRK`, `TSRKType`, `TSRKSetType()` 93f68a32c8SEmil Constantinescu M*/ 94f68a32c8SEmil Constantinescu /*MC 952e698f8bSDebojyoti Ghosh TSRK5F - Fifth order Fehlberg RK scheme with a 4th order embedded method. 96f68a32c8SEmil Constantinescu 97f68a32c8SEmil Constantinescu This method has six stages. 98f68a32c8SEmil Constantinescu 99bcf0153eSBarry Smith Options Database Key: 10067b8a455SSatish Balay . -ts_rk_type 5f - use type 5f 101287c2655SBarry Smith 102f68a32c8SEmil Constantinescu Level: advanced 103f68a32c8SEmil Constantinescu 1041cc06b55SBarry Smith .seealso: [](ch_ts), `TSRK`, `TSRKType`, `TSRKSetType()` 105f68a32c8SEmil Constantinescu M*/ 1062109b73fSDebojyoti Ghosh /*MC 107*1d27aa22SBarry Smith TSRK5DP - Fifth order Dormand-Prince RK scheme with the 4th order embedded method <https://doi.org/10.1016/0771-050X(80)90013-3> 1082109b73fSDebojyoti Ghosh 109d1905564SLisandro Dalcin This method has seven stages with the First Same As Last (FSAL) property. 1102109b73fSDebojyoti Ghosh 111bcf0153eSBarry Smith Options Database Key: 11267b8a455SSatish Balay . -ts_rk_type 5dp - use type 5dp 113287c2655SBarry Smith 1142109b73fSDebojyoti Ghosh Level: advanced 1152109b73fSDebojyoti Ghosh 1161cc06b55SBarry Smith .seealso: [](ch_ts), `TSRK`, `TSRKType`, `TSRKSetType()` 1172109b73fSDebojyoti Ghosh M*/ 11805e23783SLisandro Dalcin /*MC 119*1d27aa22SBarry Smith TSRK5BS - Fifth order Bogacki-Shampine RK scheme with 4th order embedded method <https://doi.org/10.1016/0898-1221(96)00141-1> 12005e23783SLisandro Dalcin 12105e23783SLisandro Dalcin This method has eight stages with the First Same As Last (FSAL) property. 12205e23783SLisandro Dalcin 123bcf0153eSBarry Smith Options Database Key: 12467b8a455SSatish Balay . -ts_rk_type 5bs - use type 5bs 125287c2655SBarry Smith 12605e23783SLisandro Dalcin Level: advanced 12705e23783SLisandro Dalcin 1281cc06b55SBarry Smith .seealso: [](ch_ts), `TSRK`, `TSRKType`, `TSRKSetType()` 12905e23783SLisandro Dalcin M*/ 13037acaa02SHendrik Ranocha /*MC 13137acaa02SHendrik Ranocha TSRK6VR - Sixth order robust Verner RK scheme with fifth order embedded method. 132*1d27aa22SBarry Smith <http://people.math.sfu.ca/~jverner/RKV65.IIIXb.Robust.00010102836.081204.CoeffsOnlyRAT> 13337acaa02SHendrik Ranocha 13437acaa02SHendrik Ranocha This method has nine stages with the First Same As Last (FSAL) property. 13537acaa02SHendrik Ranocha 136bcf0153eSBarry Smith Options Database Key: 13767b8a455SSatish Balay . -ts_rk_type 6vr - use type 6vr 13837acaa02SHendrik Ranocha 13937acaa02SHendrik Ranocha Level: advanced 14037acaa02SHendrik Ranocha 1411cc06b55SBarry Smith .seealso: [](ch_ts), `TSRK`, `TSRKType`, `TSRKSetType()` 14237acaa02SHendrik Ranocha M*/ 14337acaa02SHendrik Ranocha /*MC 14437acaa02SHendrik Ranocha TSRK7VR - Seventh order robust Verner RK scheme with sixth order embedded method. 145*1d27aa22SBarry Smith <http://people.math.sfu.ca/~jverner/RKV65.IIIXb.Robust.00010102836.081204.CoeffsOnlyRAT> 14637acaa02SHendrik Ranocha 1478f3d7ee2SCarsten Uphoff This method has ten stages. 14837acaa02SHendrik Ranocha 149bcf0153eSBarry Smith Options Database Key: 15067b8a455SSatish Balay . -ts_rk_type 7vr - use type 7vr 15137acaa02SHendrik Ranocha 15237acaa02SHendrik Ranocha Level: advanced 15337acaa02SHendrik Ranocha 1541cc06b55SBarry Smith .seealso: [](ch_ts), `TSRK`, `TSRKType`, `TSRKSetType()` 15537acaa02SHendrik Ranocha M*/ 15637acaa02SHendrik Ranocha /*MC 157d5b43468SJose E. Roman TSRK8VR - Eighth order robust Verner RK scheme with seventh order embedded method. 158*1d27aa22SBarry Smith <http://people.math.sfu.ca/~jverner/RKV87.IIa.Robust.00000754677.081208.CoeffsOnlyRATandFLOAT> 15937acaa02SHendrik Ranocha 1608f3d7ee2SCarsten Uphoff This method has thirteen stages. 16137acaa02SHendrik Ranocha 162bcf0153eSBarry Smith Options Database Key: 16367b8a455SSatish Balay . -ts_rk_type 8vr - use type 8vr 16437acaa02SHendrik Ranocha 16537acaa02SHendrik Ranocha Level: advanced 16637acaa02SHendrik Ranocha 1671cc06b55SBarry Smith .seealso: [](ch_ts), `TSRK`, `TSRKType`, `TSRKSetType()` 16837acaa02SHendrik Ranocha M*/ 169262ff7bbSBarry Smith 170f68a32c8SEmil Constantinescu /*@C 171bcf0153eSBarry Smith TSRKRegisterAll - Registers all of the Runge-Kutta explicit methods in `TSRK` 172262ff7bbSBarry Smith 173f68a32c8SEmil Constantinescu Not Collective, but should be called by all processes which will need the schemes to be registered 174262ff7bbSBarry Smith 175f68a32c8SEmil Constantinescu Level: advanced 176262ff7bbSBarry Smith 1771cc06b55SBarry Smith .seealso: [](ch_ts), `TSRKRegisterDestroy()`, `TSRKRegister()` 178262ff7bbSBarry Smith @*/ 179d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRKRegisterAll(void) 180d71ae5a4SJacob Faibussowitsch { 181262ff7bbSBarry Smith PetscFunctionBegin; 1823ba16761SJacob Faibussowitsch if (TSRKRegisterAllCalled) PetscFunctionReturn(PETSC_SUCCESS); 183f68a32c8SEmil Constantinescu TSRKRegisterAllCalled = PETSC_TRUE; 184e4dd521cSBarry Smith 1854e82626cSLisandro Dalcin #define RC PetscRealConstant 186e4dd521cSBarry Smith { 187b16ce868SStefano Zampini const PetscReal A[1][1] = {{0}}; 188b16ce868SStefano Zampini const PetscReal b[1] = {RC(1.0)}; 1899566063dSJacob Faibussowitsch PetscCall(TSRKRegister(TSRK1FE, 1, 1, &A[0][0], b, NULL, NULL, 0, NULL)); 190e4dd521cSBarry Smith } 191db046809SBarry Smith { 192b16ce868SStefano Zampini const PetscReal A[2][2] = { 1939371c9d4SSatish Balay {0, 0}, 1949371c9d4SSatish Balay {RC(1.0), 0} 195b16ce868SStefano Zampini }; 196b16ce868SStefano Zampini const PetscReal b[2] = {RC(0.5), RC(0.5)}; 197b16ce868SStefano Zampini const PetscReal bembed[2] = {RC(1.0), 0}; 1989566063dSJacob Faibussowitsch PetscCall(TSRKRegister(TSRK2A, 2, 2, &A[0][0], b, NULL, bembed, 0, NULL)); 199db046809SBarry Smith } 200f68a32c8SEmil Constantinescu { 201b16ce868SStefano Zampini const PetscReal A[2][2] = { 2029371c9d4SSatish Balay {0, 0}, 2039371c9d4SSatish Balay {RC(0.5), 0} 204b16ce868SStefano Zampini }; 205b16ce868SStefano Zampini const PetscReal b[2] = {0, RC(1.0)}; 2069566063dSJacob Faibussowitsch PetscCall(TSRKRegister(TSRK2B, 2, 2, &A[0][0], b, NULL, NULL, 0, NULL)); 207e7685601SHong Zhang } 208e7685601SHong Zhang { 209b16ce868SStefano Zampini const PetscReal A[3][3] = { 2109371c9d4SSatish Balay {0, 0, 0}, 2114e82626cSLisandro Dalcin {RC(2.0) / RC(3.0), 0, 0}, 2129371c9d4SSatish Balay {RC(-1.0) / RC(3.0), RC(1.0), 0} 213b16ce868SStefano Zampini }; 214b16ce868SStefano Zampini const PetscReal b[3] = {RC(0.25), RC(0.5), RC(0.25)}; 2159566063dSJacob Faibussowitsch PetscCall(TSRKRegister(TSRK3, 3, 3, &A[0][0], b, NULL, NULL, 0, NULL)); 216fdefd5e5SDebojyoti Ghosh } 217fdefd5e5SDebojyoti Ghosh { 218b16ce868SStefano Zampini const PetscReal A[4][4] = { 2199371c9d4SSatish Balay {0, 0, 0, 0}, 2204e82626cSLisandro Dalcin {RC(1.0) / RC(2.0), 0, 0, 0}, 2214e82626cSLisandro Dalcin {0, RC(3.0) / RC(4.0), 0, 0}, 2229371c9d4SSatish Balay {RC(2.0) / RC(9.0), RC(1.0) / RC(3.0), RC(4.0) / RC(9.0), 0} 223b16ce868SStefano Zampini }; 224b16ce868SStefano Zampini const PetscReal b[4] = {RC(2.0) / RC(9.0), RC(1.0) / RC(3.0), RC(4.0) / RC(9.0), 0}; 225b16ce868SStefano Zampini const PetscReal 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)}; 2269566063dSJacob Faibussowitsch PetscCall(TSRKRegister(TSRK3BS, 3, 4, &A[0][0], b, NULL, bembed, 0, NULL)); 227db046809SBarry Smith } 228f68a32c8SEmil Constantinescu { 229b16ce868SStefano Zampini const PetscReal A[4][4] = { 2309371c9d4SSatish Balay {0, 0, 0, 0}, 2314e82626cSLisandro Dalcin {RC(0.5), 0, 0, 0}, 2324e82626cSLisandro Dalcin {0, RC(0.5), 0, 0}, 2339371c9d4SSatish Balay {0, 0, RC(1.0), 0} 234b16ce868SStefano Zampini }; 235b16ce868SStefano Zampini const PetscReal 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)}; 2369566063dSJacob Faibussowitsch PetscCall(TSRKRegister(TSRK4, 4, 4, &A[0][0], b, NULL, NULL, 0, NULL)); 237db046809SBarry Smith } 238f68a32c8SEmil Constantinescu { 239b16ce868SStefano Zampini const PetscReal A[6][6] = { 2409371c9d4SSatish Balay {0, 0, 0, 0, 0, 0}, 2414e82626cSLisandro Dalcin {RC(0.25), 0, 0, 0, 0, 0}, 2424e82626cSLisandro Dalcin {RC(3.0) / RC(32.0), RC(9.0) / RC(32.0), 0, 0, 0, 0}, 2434e82626cSLisandro Dalcin {RC(1932.0) / RC(2197.0), RC(-7200.0) / RC(2197.0), RC(7296.0) / RC(2197.0), 0, 0, 0}, 2444e82626cSLisandro Dalcin {RC(439.0) / RC(216.0), RC(-8.0), RC(3680.0) / RC(513.0), RC(-845.0) / RC(4104.0), 0, 0}, 2459371c9d4SSatish Balay {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} 246b16ce868SStefano Zampini }; 247b16ce868SStefano Zampini const PetscReal 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)}; 248b16ce868SStefano Zampini const PetscReal 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}; 2499566063dSJacob Faibussowitsch PetscCall(TSRKRegister(TSRK5F, 5, 6, &A[0][0], b, NULL, bembed, 0, NULL)); 250fdefd5e5SDebojyoti Ghosh } 251fdefd5e5SDebojyoti Ghosh { 252b16ce868SStefano Zampini const PetscReal A[7][7] = { 2539371c9d4SSatish Balay {0, 0, 0, 0, 0, 0, 0}, 2544e82626cSLisandro Dalcin {RC(1.0) / RC(5.0), 0, 0, 0, 0, 0, 0}, 2554e82626cSLisandro Dalcin {RC(3.0) / RC(40.0), RC(9.0) / RC(40.0), 0, 0, 0, 0, 0}, 2564e82626cSLisandro Dalcin {RC(44.0) / RC(45.0), RC(-56.0) / RC(15.0), RC(32.0) / RC(9.0), 0, 0, 0, 0}, 2574e82626cSLisandro Dalcin {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}, 2584e82626cSLisandro Dalcin {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}, 2599371c9d4SSatish Balay {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} 260b16ce868SStefano Zampini }; 261b16ce868SStefano Zampini const PetscReal 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}; 262b16ce868SStefano Zampini const PetscReal 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)}; 263b16ce868SStefano Zampini const PetscReal binterp[7][5] = { 264b16ce868SStefano Zampini {RC(1.0), RC(-4034104133.0) / RC(1410260304.0), RC(105330401.0) / RC(33982176.0), RC(-13107642775.0) / RC(11282082432.0), RC(6542295.0) / RC(470086768.0) }, 265b16ce868SStefano Zampini {0, 0, 0, 0, 0 }, 266b16ce868SStefano Zampini {0, RC(132343189600.0) / RC(32700410799.0), RC(-833316000.0) / RC(131326951.0), RC(91412856700.0) / RC(32700410799.0), RC(-523383600.0) / RC(10900136933.0) }, 267b16ce868SStefano Zampini {0, RC(-115792950.0) / RC(29380423.0), RC(185270875.0) / RC(16991088.0), RC(-12653452475.0) / RC(1880347072.0), RC(98134425.0) / RC(235043384.0) }, 268b16ce868SStefano Zampini {0, RC(70805911779.0) / RC(24914598704.0), RC(-4531260609.0) / RC(600351776.0), RC(988140236175.0) / RC(199316789632.0), RC(-14307999165.0) / RC(24914598704.0)}, 269b16ce868SStefano Zampini {0, RC(-331320693.0) / RC(205662961.0), RC(31361737.0) / RC(7433601.0), RC(-2426908385.0) / RC(822651844.0), RC(97305120.0) / RC(205662961.0) }, 270b16ce868SStefano Zampini {0, RC(44764047.0) / RC(29380423.0), RC(-1532549.0) / RC(353981.0), RC(90730570.0) / RC(29380423.0), RC(-8293050.0) / RC(29380423.0) } 271b16ce868SStefano Zampini }; 2729566063dSJacob Faibussowitsch PetscCall(TSRKRegister(TSRK5DP, 5, 7, &A[0][0], b, NULL, bembed, 5, binterp[0])); 273f68a32c8SEmil Constantinescu } 27405e23783SLisandro Dalcin { 275b16ce868SStefano Zampini const PetscReal A[8][8] = { 2769371c9d4SSatish Balay {0, 0, 0, 0, 0, 0, 0, 0}, 2774e82626cSLisandro Dalcin {RC(1.0) / RC(6.0), 0, 0, 0, 0, 0, 0, 0}, 2784e82626cSLisandro Dalcin {RC(2.0) / RC(27.0), RC(4.0) / RC(27.0), 0, 0, 0, 0, 0, 0}, 2794e82626cSLisandro Dalcin {RC(183.0) / RC(1372.0), RC(-162.0) / RC(343.0), RC(1053.0) / RC(1372.0), 0, 0, 0, 0, 0}, 2804e82626cSLisandro Dalcin {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}, 2814e82626cSLisandro Dalcin {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}, 2824e82626cSLisandro Dalcin {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}, 2839371c9d4SSatish Balay {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} 284b16ce868SStefano Zampini }; 285b16ce868SStefano Zampini const PetscReal 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}; 286b16ce868SStefano Zampini const PetscReal 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)}; 2879566063dSJacob Faibussowitsch PetscCall(TSRKRegister(TSRK5BS, 5, 8, &A[0][0], b, NULL, bembed, 0, NULL)); 28805e23783SLisandro Dalcin } 28937acaa02SHendrik Ranocha { 290b16ce868SStefano Zampini const PetscReal A[9][9] = { 2919371c9d4SSatish Balay {0, 0, 0, 0, 0, 0, 0, 0, 0}, 29263fe90e8SHendrik Ranocha {RC(1.8000000000000000000000000000000000000000e-01), 0, 0, 0, 0, 0, 0, 0, 0}, 29363fe90e8SHendrik Ranocha {RC(8.9506172839506172839506172839506172839506e-02), RC(7.7160493827160493827160493827160493827160e-02), 0, 0, 0, 0, 0, 0, 0}, 29463fe90e8SHendrik Ranocha {RC(6.2500000000000000000000000000000000000000e-02), 0, RC(1.8750000000000000000000000000000000000000e-01), 0, 0, 0, 0, 0, 0}, 29563fe90e8SHendrik Ranocha {RC(3.1651600000000000000000000000000000000000e-01), 0, RC(-1.0449480000000000000000000000000000000000e+00), RC(1.2584320000000000000000000000000000000000e+00), 0, 0, 0, 0, 0}, 29663fe90e8SHendrik Ranocha {RC(2.7232612736485626257225065566674305502508e-01), 0, RC(-8.2513360323886639676113360323886639676113e-01), RC(1.0480917678812415654520917678812415654521e+00), RC(1.0471570799276856873679117969088177628396e-01), 0, 0, 0, 0}, 29763fe90e8SHendrik Ranocha {RC(-1.6699418599716514314329607278961797333198e-01), 0, RC(6.3170850202429149797570850202429149797571e-01), RC(1.7461044552773876082146758838488161796432e-01), RC(-1.0665356459086066122525194734018680677781e+00), RC(1.2272108843537414965986394557823129251701e+00), 0, 0, 0}, 29863fe90e8SHendrik Ranocha {RC(3.6423751686909581646423751686909581646424e-01), 0, RC(-2.0404858299595141700404858299595141700405e-01), RC(-3.4883737816068643136312309244640071707741e-01), RC(3.2619323032856867443333608747142581729048e+00), RC(-2.7551020408163265306122448979591836734694e+00), RC(6.8181818181818181818181818181818181818182e-01), 0, 0}, 2999371c9d4SSatish Balay {RC(7.6388888888888888888888888888888888888889e-02), 0, 0, RC(3.6940836940836940836940836940836940836941e-01), 0, RC(2.4801587301587301587301587301587301587302e-01), RC(2.3674242424242424242424242424242424242424e-01), RC(6.9444444444444444444444444444444444444444e-02), 0} 300b16ce868SStefano Zampini }; 301b16ce868SStefano Zampini const PetscReal b[9] = {RC(7.6388888888888888888888888888888888888889e-02), 0, 0, RC(3.6940836940836940836940836940836940836941e-01), 0, RC(2.4801587301587301587301587301587301587302e-01), RC(2.3674242424242424242424242424242424242424e-01), 302b16ce868SStefano Zampini RC(6.9444444444444444444444444444444444444444e-02), 0}; 303b16ce868SStefano Zampini const PetscReal bembed[9] = {RC(5.8700209643605870020964360587002096436059e-02), 0, 0, RC(4.8072562358276643990929705215419501133787e-01), RC(-8.5341242076919085578832094861228313083563e-01), RC(1.2046485260770975056689342403628117913832e+00), 0, RC(-5.9242373072160306202859394348756050883710e-02), RC(1.6858043453788134639198468985703028256220e-01)}; 3049566063dSJacob Faibussowitsch PetscCall(TSRKRegister(TSRK6VR, 6, 9, &A[0][0], b, NULL, bembed, 0, NULL)); 30537acaa02SHendrik Ranocha } 30637acaa02SHendrik Ranocha { 307b16ce868SStefano Zampini const PetscReal A[10][10] = { 3089371c9d4SSatish Balay {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 30963fe90e8SHendrik Ranocha {RC(5.0000000000000000000000000000000000000000e-03), 0, 0, 0, 0, 0, 0, 0, 0, 0}, 31063fe90e8SHendrik Ranocha {RC(-1.0767901234567901234567901234567901234568e+00), RC(1.1856790123456790123456790123456790123457e+00), 0, 0, 0, 0, 0, 0, 0, 0}, 31163fe90e8SHendrik Ranocha {RC(4.0833333333333333333333333333333333333333e-02), 0, RC(1.2250000000000000000000000000000000000000e-01), 0, 0, 0, 0, 0, 0, 0}, 31263fe90e8SHendrik Ranocha {RC(6.3607142857142857142857142857142857142857e-01), 0, RC(-2.4444642857142857142857142857142857142857e+00), RC(2.2633928571428571428571428571428571428571e+00), 0, 0, 0, 0, 0, 0}, 31363fe90e8SHendrik Ranocha {RC(-2.5351211079349245229256383554660215487207e+00), 0, RC(1.0299374654449267920438514460756024913612e+01), RC(-7.9513032885990579949493217458266876536482e+00), RC(7.9301148923100592201226014271115261823800e-01), 0, 0, 0, 0, 0}, 31463fe90e8SHendrik Ranocha {RC(1.0018765812524632961969196583094999808207e+00), 0, RC(-4.1665712824423798331313938005470971453189e+00), RC(3.8343432929128642412552665218251378665197e+00), RC(-5.0233333560710847547464330228611765612403e-01), RC(6.6768474388416077115385092269857695410259e-01), 0, 0, 0, 0}, 31563fe90e8SHendrik Ranocha {RC(2.7255018354630767130333963819175005717348e+01), 0, RC(-4.2004617278410638355318645443909295369611e+01), RC(-1.0535713126619489917921081600546526103722e+01), RC(8.0495536711411937147983652158926826634202e+01), RC(-6.7343882271790513468549075963212975640927e+01), RC(1.3048657610777937463471187029566964762710e+01), 0, 0, 0}, 31663fe90e8SHendrik Ranocha {RC(-3.0397378057114965146943658658755763226883e+00), 0, RC(1.0138161410329801111857946190709700150441e+01), RC(-6.4293056748647215721462825629555298064437e+00), RC(-1.5864371483408276587115312853798610579467e+00), RC(1.8921781841968424410864308909131353365021e+00), RC(1.9699335407608869061292360163336442838006e-02), RC(5.4416989827933235465102724247952572977903e-03), 0, 0}, 3179371c9d4SSatish Balay {RC(-1.4449518916777735137351003179355712360517e+00), 0, RC(8.0318913859955919224117033223019560435041e+00), RC(-7.5831741663401346820798883023671588604984e+00), RC(3.5816169353190074211247685442452878696855e+00), RC(-2.4369722632199529411183809065693752383733e+00), RC(8.5158999992326179339689766032486142173390e-01), 0, 0, 0} 318b16ce868SStefano Zampini }; 319b16ce868SStefano Zampini const PetscReal b[10] = {RC(4.7425837833706756083569172717574534698932e-02), 0, 0, RC(2.5622361659370562659961727458274623448160e-01), RC(2.6951376833074206619473817258075952886764e-01), RC(1.2686622409092782845989138364739173247882e-01), RC(2.4887225942060071622046449427647492767292e-01), RC(3.0744837408200631335304388479099184768645e-03), RC(4.8023809989496943308189063347143123323209e-02), 0}; 320b16ce868SStefano Zampini const PetscReal bembed[10] = {RC(4.7485247699299631037531273805727961552268e-02), 0, 0, RC(2.5599412588690633297154918245905393870497e-01), RC(2.7058478081067688722530891099268135732387e-01), RC(1.2505618684425992913638822323746917920448e-01), 3219371c9d4SSatish Balay RC(2.5204468723743860507184043820197442562182e-01), 0, 0, RC(4.8834971521418614557381971303093137592592e-02)}; 3229566063dSJacob Faibussowitsch PetscCall(TSRKRegister(TSRK7VR, 7, 10, &A[0][0], b, NULL, bembed, 0, NULL)); 32337acaa02SHendrik Ranocha } 32437acaa02SHendrik Ranocha { 325b16ce868SStefano Zampini const PetscReal A[13][13] = { 3269371c9d4SSatish Balay {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 32763fe90e8SHendrik Ranocha {RC(2.5000000000000000000000000000000000000000e-01), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 32863fe90e8SHendrik Ranocha {RC(8.7400846504915232052686327594877411977046e-02), RC(2.5487604938654321753087950620345685135815e-02), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 32963fe90e8SHendrik Ranocha {RC(4.2333169291338582677165354330708661417323e-02), 0, RC(1.2699950787401574803149606299212598425197e-01), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 33063fe90e8SHendrik Ranocha {RC(4.2609505888742261494881445237572274090942e-01), 0, RC(-1.5987952846591523265427733230657181117089e+00), RC(1.5967002257717297115939588706899953707994e+00), 0, 0, 0, 0, 0, 0, 0, 0, 0}, 33163fe90e8SHendrik Ranocha {RC(5.0719337296713929515090618138513639239329e-02), 0, 0, RC(2.5433377264600407582754714408877778031369e-01), RC(2.0394689005728199465736223777270858044698e-01), 0, 0, 0, 0, 0, 0, 0, 0}, 33263fe90e8SHendrik Ranocha {RC(-2.9000374717523110970388379285425896124091e-01), 0, 0, RC(1.3441873910260789889438681109414337003184e+00), RC(-2.8647779433614427309611103827036562829470e+00), RC(2.6775942995105948517211260646164815438695e+00), 0, 0, 0, 0, 0, 0, 0}, 33363fe90e8SHendrik Ranocha {RC(9.8535011337993546469740402980727014284756e-02), 0, 0, 0, RC(2.2192680630751384842024036498197387903583e-01), RC(-1.8140622911806994312690338288073952457474e-01), RC(1.0944411472562548236922614918038631254153e-02), 0, 0, 0, 0, 0, 0}, 33463fe90e8SHendrik Ranocha {RC(3.8711052545731144679444618165166373405645e-01), 0, 0, RC(-1.4424454974855277571256745553077927767173e+00), RC(2.9053981890699509317691346449233848441744e+00), RC(-1.8537710696301059290843332675811978025183e+00), RC(1.4003648098728154269497325109771241479223e-01), RC(5.7273940811495816575746774624447706488753e-01), 0, 0, 0, 0, 0}, 33563fe90e8SHendrik Ranocha {RC(-1.6124403444439308100630016197913480595436e-01), 0, 0, RC(-1.7339602957358984083578404473962567894901e-01), RC(-1.3012892814065147406016812745172492529744e+00), RC(1.1379503751738617308558792131431003472124e+00), RC(-3.1747649663966880106923521138043024698980e-02), RC(9.3351293824933666439811064486056884856590e-01), RC(-8.3786318334733852703300855629616433201504e-02), 0, 0, 0, 0}, 33663fe90e8SHendrik Ranocha {RC(-1.9199444881589533281510804651483576073142e-02), 0, 0, RC(2.7330857265264284907942326254016124275617e-01), RC(-6.7534973206944372919691611210942380856240e-01), RC(3.4151849813846016071738489974728382711981e-01), RC(-6.7950064803375772478920516198524629391910e-02), RC(9.6591752247623878884265586491216376509746e-02), RC(1.3253082511182101180721038466545389951226e-01), RC(3.6854959360386113446906329951531666812946e-01), 0, 0, 0}, 33763fe90e8SHendrik Ranocha {RC(6.0918774036452898676888412111588817784584e-01), 0, 0, RC(-2.2725690858980016768999800931413088399719e+00), RC(4.7578983426940290068155255881914785497547e+00), RC(-5.5161067066927584824294689667844248244842e+00), RC(2.9005963696801192709095818565946174378180e-01), RC(5.6914239633590368229109858454801849145630e-01), RC(7.9267957603321670271339916205893327579951e-01), RC(1.5473720453288822894126190771849898232047e-01), RC(1.6149708956621816247083215106334544434974e+00), 0, 0}, 3389371c9d4SSatish Balay {RC(8.8735762208534719663211694051981022704884e-01), 0, 0, RC(-2.9754597821085367558513632804709301581977e+00), RC(5.6007170094881630597990392548350098923829e+00), RC(-5.9156074505366744680014930189941657351840e+00), RC(2.2029689156134927016879142540807638331238e-01), RC(1.0155097824462216666143271340902996997549e-01), RC(1.1514345647386055909780397752125850553556e+00), RC(1.9297101665271239396134361900805843653065e+00), 0, 0, 0} 339b16ce868SStefano Zampini }; 340b16ce868SStefano Zampini const PetscReal b[13] = {RC(4.4729564666695714203015840429049382466467e-02), 0, 0, 0, 0, RC(1.5691033527708199813368698010726645409175e-01), RC(1.8460973408151637740702451873526277892035e-01), RC(2.2516380602086991042479419400350721970920e-01), RC(1.4794615651970234687005179885449141753736e-01), RC(7.6055542444955825269798361910336491012732e-02), RC(1.2277290235018619610824346315921437388535e-01), RC(4.1811958638991631583384842800871882376786e-02), 0}; 341b16ce868SStefano Zampini const PetscReal bembed[13] = {RC(4.5847111400495925878664730122010282095875e-02), 0, 0, 0, 0, RC(2.6231891404152387437443356584845803392392e-01), RC(1.9169372337852611904485738635688429008025e-01), RC(2.1709172327902618330978407422906448568196e-01), RC(1.2738189624833706796803169450656737867900e-01), RC(1.1510530385365326258240515750043192148894e-01), 0, 0, RC(4.0561327798437566841823391436583608050053e-02)}; 3429566063dSJacob Faibussowitsch PetscCall(TSRKRegister(TSRK8VR, 8, 13, &A[0][0], b, NULL, bembed, 0, NULL)); 34337acaa02SHendrik Ranocha } 3444e82626cSLisandro Dalcin #undef RC 3453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 346db046809SBarry Smith } 347db046809SBarry Smith 348f68a32c8SEmil Constantinescu /*@C 349bcf0153eSBarry Smith TSRKRegisterDestroy - Frees the list of schemes that were registered by `TSRKRegister()`. 350f68a32c8SEmil Constantinescu 351f68a32c8SEmil Constantinescu Not Collective 352f68a32c8SEmil Constantinescu 353f68a32c8SEmil Constantinescu Level: advanced 354f68a32c8SEmil Constantinescu 3551cc06b55SBarry Smith .seealso: [](ch_ts), `TSRK`, `TSRKRegister()`, `TSRKRegisterAll()` 356f68a32c8SEmil Constantinescu @*/ 357d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRKRegisterDestroy(void) 358d71ae5a4SJacob Faibussowitsch { 359f68a32c8SEmil Constantinescu RKTableauLink link; 360f68a32c8SEmil Constantinescu 361f68a32c8SEmil Constantinescu PetscFunctionBegin; 362f68a32c8SEmil Constantinescu while ((link = RKTableauList)) { 363f68a32c8SEmil Constantinescu RKTableau t = &link->tab; 364f68a32c8SEmil Constantinescu RKTableauList = link->next; 3659566063dSJacob Faibussowitsch PetscCall(PetscFree3(t->A, t->b, t->c)); 3669566063dSJacob Faibussowitsch PetscCall(PetscFree(t->bembed)); 3679566063dSJacob Faibussowitsch PetscCall(PetscFree(t->binterp)); 3689566063dSJacob Faibussowitsch PetscCall(PetscFree(t->name)); 3699566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 370f68a32c8SEmil Constantinescu } 371f68a32c8SEmil Constantinescu TSRKRegisterAllCalled = PETSC_FALSE; 3723ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 373f68a32c8SEmil Constantinescu } 374f68a32c8SEmil Constantinescu 375f68a32c8SEmil Constantinescu /*@C 376bcf0153eSBarry Smith TSRKInitializePackage - This function initializes everything in the `TSRK` package. It is called 377bcf0153eSBarry Smith from `TSInitializePackage()`. 378f68a32c8SEmil Constantinescu 379f68a32c8SEmil Constantinescu Level: developer 380f68a32c8SEmil Constantinescu 3811cc06b55SBarry Smith .seealso: [](ch_ts), `TSInitializePackage()`, `PetscInitialize()`, `TSRKFinalizePackage()` 382f68a32c8SEmil Constantinescu @*/ 383d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRKInitializePackage(void) 384d71ae5a4SJacob Faibussowitsch { 385e4dd521cSBarry Smith PetscFunctionBegin; 3863ba16761SJacob Faibussowitsch if (TSRKPackageInitialized) PetscFunctionReturn(PETSC_SUCCESS); 387f68a32c8SEmil Constantinescu TSRKPackageInitialized = PETSC_TRUE; 3889566063dSJacob Faibussowitsch PetscCall(TSRKRegisterAll()); 3899566063dSJacob Faibussowitsch PetscCall(PetscRegisterFinalize(TSRKFinalizePackage)); 3903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 391f68a32c8SEmil Constantinescu } 392186e87acSLisandro Dalcin 393f68a32c8SEmil Constantinescu /*@C 394bcf0153eSBarry Smith TSRKFinalizePackage - This function destroys everything in the `TSRK` package. It is 395bcf0153eSBarry Smith called from `PetscFinalize()`. 396186e87acSLisandro Dalcin 397f68a32c8SEmil Constantinescu Level: developer 398f68a32c8SEmil Constantinescu 3991cc06b55SBarry Smith .seealso: [](ch_ts), `PetscFinalize()`, `TSRKInitializePackage()` 400f68a32c8SEmil Constantinescu @*/ 401d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRKFinalizePackage(void) 402d71ae5a4SJacob Faibussowitsch { 403f68a32c8SEmil Constantinescu PetscFunctionBegin; 404f68a32c8SEmil Constantinescu TSRKPackageInitialized = PETSC_FALSE; 4059566063dSJacob Faibussowitsch PetscCall(TSRKRegisterDestroy()); 4063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 407f68a32c8SEmil Constantinescu } 408f68a32c8SEmil Constantinescu 409f68a32c8SEmil Constantinescu /*@C 410bcf0153eSBarry Smith TSRKRegister - register an `TSRK` scheme by providing the entries in the Butcher tableau and optionally embedded approximations and interpolation 411f68a32c8SEmil Constantinescu 412f68a32c8SEmil Constantinescu Not Collective, but the same schemes should be registered on all processes on which they will be used 413f68a32c8SEmil Constantinescu 414f68a32c8SEmil Constantinescu Input Parameters: 415f68a32c8SEmil Constantinescu + name - identifier for method 416f68a32c8SEmil Constantinescu . order - approximation order of method 417f68a32c8SEmil Constantinescu . s - number of stages, this is the dimension of the matrices below 418f68a32c8SEmil Constantinescu . A - stage coefficients (dimension s*s, row-major) 419f68a32c8SEmil Constantinescu . b - step completion table (dimension s; NULL to use last row of A) 420f68a32c8SEmil Constantinescu . c - abscissa (dimension s; NULL to use row sums of A) 421f68a32c8SEmil Constantinescu . bembed - completion table for embedded method (dimension s; NULL if not available) 4223a8a9803SLisandro Dalcin . p - Order of the interpolation scheme, equal to the number of columns of binterp 4233a8a9803SLisandro Dalcin - binterp - Coefficients of the interpolation formula (dimension s*p; NULL to reuse b with p=1) 424f68a32c8SEmil Constantinescu 425f68a32c8SEmil Constantinescu Level: advanced 426f68a32c8SEmil Constantinescu 427bcf0153eSBarry Smith Note: 428bcf0153eSBarry Smith Several `TSRK` methods are provided, this function is only needed to create new methods. 429bcf0153eSBarry Smith 4301cc06b55SBarry Smith .seealso: [](ch_ts), `TSRK` 431f68a32c8SEmil Constantinescu @*/ 432d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRKRegister(TSRKType name, PetscInt order, PetscInt s, const PetscReal A[], const PetscReal b[], const PetscReal c[], const PetscReal bembed[], PetscInt p, const PetscReal binterp[]) 433d71ae5a4SJacob Faibussowitsch { 434f68a32c8SEmil Constantinescu RKTableauLink link; 435f68a32c8SEmil Constantinescu RKTableau t; 436f68a32c8SEmil Constantinescu PetscInt i, j; 437f68a32c8SEmil Constantinescu 438f68a32c8SEmil Constantinescu PetscFunctionBegin; 4394f572ea9SToby Isaac PetscAssertPointer(name, 1); 4404f572ea9SToby Isaac PetscAssertPointer(A, 4); 4414f572ea9SToby Isaac if (b) PetscAssertPointer(b, 5); 4424f572ea9SToby Isaac if (c) PetscAssertPointer(c, 6); 4434f572ea9SToby Isaac if (bembed) PetscAssertPointer(bembed, 7); 4444f572ea9SToby Isaac if (binterp || p > 1) PetscAssertPointer(binterp, 9); 445095c51faSJed Brown PetscCheck(s >= 0, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Expected number of stages s %" PetscInt_FMT " >= 0", s); 4463a8a9803SLisandro Dalcin 4479566063dSJacob Faibussowitsch PetscCall(TSRKInitializePackage()); 4489566063dSJacob Faibussowitsch PetscCall(PetscNew(&link)); 449f68a32c8SEmil Constantinescu t = &link->tab; 4503a8a9803SLisandro Dalcin 4519566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(name, &t->name)); 452f68a32c8SEmil Constantinescu t->order = order; 453f68a32c8SEmil Constantinescu t->s = s; 4549566063dSJacob Faibussowitsch PetscCall(PetscMalloc3(s * s, &t->A, s, &t->b, s, &t->c)); 4559566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(t->A, A, s * s)); 4569566063dSJacob Faibussowitsch if (b) PetscCall(PetscArraycpy(t->b, b, s)); 4579371c9d4SSatish Balay else 4589371c9d4SSatish Balay for (i = 0; i < s; i++) t->b[i] = A[(s - 1) * s + i]; 4599566063dSJacob Faibussowitsch if (c) PetscCall(PetscArraycpy(t->c, c, s)); 4609371c9d4SSatish Balay else 4619371c9d4SSatish Balay for (i = 0; i < s; i++) 4629371c9d4SSatish Balay for (j = 0, t->c[i] = 0; j < s; j++) t->c[i] += A[i * s + j]; 463d760c35bSDebojyoti Ghosh t->FSAL = PETSC_TRUE; 4649371c9d4SSatish Balay for (i = 0; i < s; i++) 4659371c9d4SSatish Balay if (t->A[(s - 1) * s + i] != t->b[i]) t->FSAL = PETSC_FALSE; 4663a8a9803SLisandro Dalcin 467f68a32c8SEmil Constantinescu if (bembed) { 4689566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(s, &t->bembed)); 4699566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(t->bembed, bembed, s)); 470f68a32c8SEmil Constantinescu } 471f68a32c8SEmil Constantinescu 4729371c9d4SSatish Balay if (!binterp) { 4739371c9d4SSatish Balay p = 1; 4749371c9d4SSatish Balay binterp = t->b; 4759371c9d4SSatish Balay } 4763a8a9803SLisandro Dalcin t->p = p; 4779566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(s * p, &t->binterp)); 4789566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(t->binterp, binterp, s * p)); 4793a8a9803SLisandro Dalcin 480f68a32c8SEmil Constantinescu link->next = RKTableauList; 481f68a32c8SEmil Constantinescu RKTableauList = link; 4823ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 483f68a32c8SEmil Constantinescu } 484f68a32c8SEmil Constantinescu 48566976f2fSJacob Faibussowitsch static PetscErrorCode TSRKGetTableau_RK(TS ts, PetscInt *s, const PetscReal **A, const PetscReal **b, const PetscReal **c, const PetscReal **bembed, PetscInt *p, const PetscReal **binterp, PetscBool *FSAL) 486d71ae5a4SJacob Faibussowitsch { 4870f7a28cdSStefano Zampini TS_RK *rk = (TS_RK *)ts->data; 4880f7a28cdSStefano Zampini RKTableau tab = rk->tableau; 4890f7a28cdSStefano Zampini 4900f7a28cdSStefano Zampini PetscFunctionBegin; 4910f7a28cdSStefano Zampini if (s) *s = tab->s; 4920f7a28cdSStefano Zampini if (A) *A = tab->A; 4930f7a28cdSStefano Zampini if (b) *b = tab->b; 4940f7a28cdSStefano Zampini if (c) *c = tab->c; 4950f7a28cdSStefano Zampini if (bembed) *bembed = tab->bembed; 4960f7a28cdSStefano Zampini if (p) *p = tab->p; 4970f7a28cdSStefano Zampini if (binterp) *binterp = tab->binterp; 4980f7a28cdSStefano Zampini if (FSAL) *FSAL = tab->FSAL; 4993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5000f7a28cdSStefano Zampini } 5010f7a28cdSStefano Zampini 5020f7a28cdSStefano Zampini /*@C 503bcf0153eSBarry Smith TSRKGetTableau - Get info on the `TSRK` tableau 5040f7a28cdSStefano Zampini 5050f7a28cdSStefano Zampini Not Collective 5060f7a28cdSStefano Zampini 507f899ff85SJose E. Roman Input Parameter: 5080f7a28cdSStefano Zampini . ts - timestepping context 5090f7a28cdSStefano Zampini 5100f7a28cdSStefano Zampini Output Parameters: 5110f7a28cdSStefano Zampini + s - number of stages, this is the dimension of the matrices below 5120f7a28cdSStefano Zampini . A - stage coefficients (dimension s*s, row-major) 5130f7a28cdSStefano Zampini . b - step completion table (dimension s) 5140f7a28cdSStefano Zampini . c - abscissa (dimension s) 5150f7a28cdSStefano Zampini . bembed - completion table for embedded method (dimension s; NULL if not available) 5160f7a28cdSStefano Zampini . p - Order of the interpolation scheme, equal to the number of columns of binterp 5170f7a28cdSStefano Zampini . binterp - Coefficients of the interpolation formula (dimension s*p) 518aaa8cc7dSPierre Jolivet - FSAL - whether or not the scheme has the First Same As Last property 5190f7a28cdSStefano Zampini 5200f7a28cdSStefano Zampini Level: developer 5210f7a28cdSStefano Zampini 5221cc06b55SBarry Smith .seealso: [](ch_ts), `TSRK`, `TSRKRegister()`, `TSRKSetType()` 5230f7a28cdSStefano Zampini @*/ 524d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRKGetTableau(TS ts, PetscInt *s, const PetscReal **A, const PetscReal **b, const PetscReal **c, const PetscReal **bembed, PetscInt *p, const PetscReal **binterp, PetscBool *FSAL) 525d71ae5a4SJacob Faibussowitsch { 5260f7a28cdSStefano Zampini PetscFunctionBegin; 5270f7a28cdSStefano Zampini PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 5289371c9d4SSatish Balay PetscUseMethod(ts, "TSRKGetTableau_C", (TS, PetscInt *, const PetscReal **, const PetscReal **, const PetscReal **, const PetscReal **, PetscInt *, const PetscReal **, PetscBool *), (ts, s, A, b, c, bembed, p, binterp, FSAL)); 5293ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5300f7a28cdSStefano Zampini } 5310f7a28cdSStefano Zampini 532e4dd521cSBarry Smith /* 5332c9cb062Sluzhanghpp This is for single-step RK method 534f68a32c8SEmil Constantinescu The step completion formula is 535e4dd521cSBarry Smith 536f68a32c8SEmil Constantinescu x1 = x0 + h b^T YdotRHS 537f68a32c8SEmil Constantinescu 538f68a32c8SEmil Constantinescu This function can be called before or after ts->vec_sol has been updated. 539f68a32c8SEmil Constantinescu Suppose we have a completion formula (b) and an embedded formula (be) of different order. 540f68a32c8SEmil Constantinescu We can write 541f68a32c8SEmil Constantinescu 542f68a32c8SEmil Constantinescu x1e = x0 + h be^T YdotRHS 543f68a32c8SEmil Constantinescu = x1 - h b^T YdotRHS + h be^T YdotRHS 544f68a32c8SEmil Constantinescu = x1 + h (be - b)^T YdotRHS 545f68a32c8SEmil Constantinescu 546f68a32c8SEmil Constantinescu so we can evaluate the method with different order even after the step has been optimistically completed. 547e4dd521cSBarry Smith */ 548d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSEvaluateStep_RK(TS ts, PetscInt order, Vec X, PetscBool *done) 549d71ae5a4SJacob Faibussowitsch { 550f68a32c8SEmil Constantinescu TS_RK *rk = (TS_RK *)ts->data; 551f68a32c8SEmil Constantinescu RKTableau tab = rk->tableau; 552f68a32c8SEmil Constantinescu PetscScalar *w = rk->work; 553f68a32c8SEmil Constantinescu PetscReal h; 554f68a32c8SEmil Constantinescu PetscInt s = tab->s, j; 555f68a32c8SEmil Constantinescu 556f68a32c8SEmil Constantinescu PetscFunctionBegin; 557f68a32c8SEmil Constantinescu switch (rk->status) { 558f68a32c8SEmil Constantinescu case TS_STEP_INCOMPLETE: 559d71ae5a4SJacob Faibussowitsch case TS_STEP_PENDING: 560d71ae5a4SJacob Faibussowitsch h = ts->time_step; 561d71ae5a4SJacob Faibussowitsch break; 562d71ae5a4SJacob Faibussowitsch case TS_STEP_COMPLETE: 563d71ae5a4SJacob Faibussowitsch h = ts->ptime - ts->ptime_prev; 564d71ae5a4SJacob Faibussowitsch break; 565d71ae5a4SJacob Faibussowitsch default: 566d71ae5a4SJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)ts), PETSC_ERR_PLIB, "Invalid TSStepStatus"); 567f68a32c8SEmil Constantinescu } 568f68a32c8SEmil Constantinescu if (order == tab->order) { 569f68a32c8SEmil Constantinescu if (rk->status == TS_STEP_INCOMPLETE) { 5709566063dSJacob Faibussowitsch PetscCall(VecCopy(ts->vec_sol, X)); 57190b67129SHong Zhang for (j = 0; j < s; j++) w[j] = h * tab->b[j] / rk->dtratio; 5729566063dSJacob Faibussowitsch PetscCall(VecMAXPY(X, s, w, rk->YdotRHS)); 5739566063dSJacob Faibussowitsch } else PetscCall(VecCopy(ts->vec_sol, X)); 5743ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 575f68a32c8SEmil Constantinescu } else if (order == tab->order - 1) { 576f68a32c8SEmil Constantinescu if (!tab->bembed) goto unavailable; 577f68a32c8SEmil Constantinescu if (rk->status == TS_STEP_INCOMPLETE) { /*Complete with the embedded method (be)*/ 5789566063dSJacob Faibussowitsch PetscCall(VecCopy(ts->vec_sol, X)); 579f68a32c8SEmil Constantinescu for (j = 0; j < s; j++) w[j] = h * tab->bembed[j]; 5809566063dSJacob Faibussowitsch PetscCall(VecMAXPY(X, s, w, rk->YdotRHS)); 581f68a32c8SEmil Constantinescu } else { /*Rollback and re-complete using (be-b) */ 5829566063dSJacob Faibussowitsch PetscCall(VecCopy(ts->vec_sol, X)); 583f68a32c8SEmil Constantinescu for (j = 0; j < s; j++) w[j] = h * (tab->bembed[j] - tab->b[j]); 5849566063dSJacob Faibussowitsch PetscCall(VecMAXPY(X, s, w, rk->YdotRHS)); 585f68a32c8SEmil Constantinescu } 586f68a32c8SEmil Constantinescu if (done) *done = PETSC_TRUE; 5873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 588f68a32c8SEmil Constantinescu } 589f68a32c8SEmil Constantinescu unavailable: 590f68a32c8SEmil Constantinescu if (done) *done = PETSC_FALSE; 5919371c9d4SSatish Balay else 5929371c9d4SSatish Balay SETERRQ(PetscObjectComm((PetscObject)ts), PETSC_ERR_SUP, "RK '%s' of order %" PetscInt_FMT " cannot evaluate step at order %" PetscInt_FMT ". Consider using -ts_adapt_type none or a different method that has an embedded estimate.", tab->name, tab->order, order); 5933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 594f68a32c8SEmil Constantinescu } 595f68a32c8SEmil Constantinescu 596d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSForwardCostIntegral_RK(TS ts) 597d71ae5a4SJacob Faibussowitsch { 5980f7a1166SHong Zhang TS_RK *rk = (TS_RK *)ts->data; 599cd4cee2dSHong Zhang TS quadts = ts->quadraturets; 6000f7a1166SHong Zhang RKTableau tab = rk->tableau; 6010f7a1166SHong Zhang const PetscInt s = tab->s; 6020f7a1166SHong Zhang const PetscReal *b = tab->b, *c = tab->c; 6030f7a1166SHong Zhang Vec *Y = rk->Y; 6040f7a1166SHong Zhang PetscInt i; 6050f7a1166SHong Zhang 6060f7a1166SHong Zhang PetscFunctionBegin; 607cd4cee2dSHong Zhang /* No need to backup quadts->vec_sol since it can be reverted in TSRollBack_RK */ 6080f7a1166SHong Zhang for (i = s - 1; i >= 0; i--) { 609cd4cee2dSHong Zhang /* Evolve quadrature TS solution to compute integrals */ 6109566063dSJacob Faibussowitsch PetscCall(TSComputeRHSFunction(quadts, rk->ptime + rk->time_step * c[i], Y[i], ts->vec_costintegrand)); 6119566063dSJacob Faibussowitsch PetscCall(VecAXPY(quadts->vec_sol, rk->time_step * b[i], ts->vec_costintegrand)); 6120f7a1166SHong Zhang } 6133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6140f7a1166SHong Zhang } 6150f7a1166SHong Zhang 616d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSAdjointCostIntegral_RK(TS ts) 617d71ae5a4SJacob Faibussowitsch { 6180f7a1166SHong Zhang TS_RK *rk = (TS_RK *)ts->data; 6190f7a1166SHong Zhang RKTableau tab = rk->tableau; 620cd4cee2dSHong Zhang TS quadts = ts->quadraturets; 6210f7a1166SHong Zhang const PetscInt s = tab->s; 6220f7a1166SHong Zhang const PetscReal *b = tab->b, *c = tab->c; 6230f7a1166SHong Zhang Vec *Y = rk->Y; 6240f7a1166SHong Zhang PetscInt i; 6250f7a1166SHong Zhang 6260f7a1166SHong Zhang PetscFunctionBegin; 6270f7a1166SHong Zhang for (i = s - 1; i >= 0; i--) { 628cd4cee2dSHong Zhang /* Evolve quadrature TS solution to compute integrals */ 6299566063dSJacob Faibussowitsch PetscCall(TSComputeRHSFunction(quadts, ts->ptime + ts->time_step * (1.0 - c[i]), Y[i], ts->vec_costintegrand)); 6309566063dSJacob Faibussowitsch PetscCall(VecAXPY(quadts->vec_sol, -ts->time_step * b[i], ts->vec_costintegrand)); 6310f7a1166SHong Zhang } 6323ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6330f7a1166SHong Zhang } 6340f7a1166SHong Zhang 635d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSRollBack_RK(TS ts) 636d71ae5a4SJacob Faibussowitsch { 637fecfb714SLisandro Dalcin TS_RK *rk = (TS_RK *)ts->data; 638cd4cee2dSHong Zhang TS quadts = ts->quadraturets; 639fecfb714SLisandro Dalcin RKTableau tab = rk->tableau; 640fecfb714SLisandro Dalcin const PetscInt s = tab->s; 641cd4cee2dSHong Zhang const PetscReal *b = tab->b, *c = tab->c; 642fecfb714SLisandro Dalcin PetscScalar *w = rk->work; 643cd4cee2dSHong Zhang Vec *Y = rk->Y, *YdotRHS = rk->YdotRHS; 644fecfb714SLisandro Dalcin PetscInt j; 645fecfb714SLisandro Dalcin PetscReal h; 646fecfb714SLisandro Dalcin 647fecfb714SLisandro Dalcin PetscFunctionBegin; 648fecfb714SLisandro Dalcin switch (rk->status) { 649fecfb714SLisandro Dalcin case TS_STEP_INCOMPLETE: 650d71ae5a4SJacob Faibussowitsch case TS_STEP_PENDING: 651d71ae5a4SJacob Faibussowitsch h = ts->time_step; 652d71ae5a4SJacob Faibussowitsch break; 653d71ae5a4SJacob Faibussowitsch case TS_STEP_COMPLETE: 654d71ae5a4SJacob Faibussowitsch h = ts->ptime - ts->ptime_prev; 655d71ae5a4SJacob Faibussowitsch break; 656d71ae5a4SJacob Faibussowitsch default: 657d71ae5a4SJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)ts), PETSC_ERR_PLIB, "Invalid TSStepStatus"); 658fecfb714SLisandro Dalcin } 659fecfb714SLisandro Dalcin for (j = 0; j < s; j++) w[j] = -h * b[j]; 6609566063dSJacob Faibussowitsch PetscCall(VecMAXPY(ts->vec_sol, s, w, YdotRHS)); 661cd4cee2dSHong Zhang if (quadts && ts->costintegralfwd) { 662cd4cee2dSHong Zhang for (j = 0; j < s; j++) { 663cd4cee2dSHong Zhang /* Revert the quadrature TS solution */ 6649566063dSJacob Faibussowitsch PetscCall(TSComputeRHSFunction(quadts, rk->ptime + h * c[j], Y[j], ts->vec_costintegrand)); 6659566063dSJacob Faibussowitsch PetscCall(VecAXPY(quadts->vec_sol, -h * b[j], ts->vec_costintegrand)); 666cd4cee2dSHong Zhang } 667cd4cee2dSHong Zhang } 6683ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 669fecfb714SLisandro Dalcin } 670fecfb714SLisandro Dalcin 671d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSForwardStep_RK(TS ts) 672d71ae5a4SJacob Faibussowitsch { 673922a638cSHong Zhang TS_RK *rk = (TS_RK *)ts->data; 674922a638cSHong Zhang RKTableau tab = rk->tableau; 675922a638cSHong Zhang Mat J, *MatsFwdSensipTemp = rk->MatsFwdSensipTemp; 676922a638cSHong Zhang const PetscInt s = tab->s; 677922a638cSHong Zhang const PetscReal *A = tab->A, *c = tab->c, *b = tab->b; 678922a638cSHong Zhang Vec *Y = rk->Y; 679922a638cSHong Zhang PetscInt i, j; 680922a638cSHong Zhang PetscReal stage_time, h = ts->time_step; 681922a638cSHong Zhang PetscBool zero; 682922a638cSHong Zhang 683922a638cSHong Zhang PetscFunctionBegin; 6849566063dSJacob Faibussowitsch PetscCall(MatCopy(ts->mat_sensip, rk->MatFwdSensip0, SAME_NONZERO_PATTERN)); 6859566063dSJacob Faibussowitsch PetscCall(TSGetRHSJacobian(ts, &J, NULL, NULL, NULL)); 686922a638cSHong Zhang 687922a638cSHong Zhang for (i = 0; i < s; i++) { 688922a638cSHong Zhang stage_time = ts->ptime + h * c[i]; 689922a638cSHong Zhang zero = PETSC_FALSE; 690922a638cSHong Zhang if (b[i] == 0 && i == s - 1) zero = PETSC_TRUE; 691922a638cSHong Zhang /* TLM Stage values */ 692922a638cSHong Zhang if (!i) { 6939566063dSJacob Faibussowitsch PetscCall(MatCopy(ts->mat_sensip, rk->MatsFwdStageSensip[i], SAME_NONZERO_PATTERN)); 694922a638cSHong Zhang } else if (!zero) { 6959566063dSJacob Faibussowitsch PetscCall(MatZeroEntries(rk->MatsFwdStageSensip[i])); 69648a46eb9SPierre Jolivet for (j = 0; j < i; j++) PetscCall(MatAXPY(rk->MatsFwdStageSensip[i], h * A[i * s + j], MatsFwdSensipTemp[j], SAME_NONZERO_PATTERN)); 6979566063dSJacob Faibussowitsch PetscCall(MatAXPY(rk->MatsFwdStageSensip[i], 1., ts->mat_sensip, SAME_NONZERO_PATTERN)); 698922a638cSHong Zhang } else { 6999566063dSJacob Faibussowitsch PetscCall(MatZeroEntries(rk->MatsFwdStageSensip[i])); 700922a638cSHong Zhang } 701922a638cSHong Zhang 7029566063dSJacob Faibussowitsch PetscCall(TSComputeRHSJacobian(ts, stage_time, Y[i], J, J)); 7039566063dSJacob Faibussowitsch PetscCall(MatMatMult(J, rk->MatsFwdStageSensip[i], MAT_REUSE_MATRIX, PETSC_DEFAULT, &MatsFwdSensipTemp[i])); 70413af1a74SHong Zhang if (ts->Jacprhs) { 7059566063dSJacob Faibussowitsch PetscCall(TSComputeRHSJacobianP(ts, stage_time, Y[i], ts->Jacprhs)); /* get f_p */ 70613af1a74SHong Zhang if (ts->vecs_sensi2p) { /* TLM used for 2nd-order adjoint */ 70713af1a74SHong Zhang PetscScalar *xarr; 7089566063dSJacob Faibussowitsch PetscCall(MatDenseGetColumn(MatsFwdSensipTemp[i], 0, &xarr)); 7099566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(rk->VecDeltaFwdSensipCol, xarr)); 7109566063dSJacob Faibussowitsch PetscCall(MatMultAdd(ts->Jacprhs, ts->vec_dir, rk->VecDeltaFwdSensipCol, rk->VecDeltaFwdSensipCol)); 7119566063dSJacob Faibussowitsch PetscCall(VecResetArray(rk->VecDeltaFwdSensipCol)); 7129566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreColumn(MatsFwdSensipTemp[i], &xarr)); 71313af1a74SHong Zhang } else { 7149566063dSJacob Faibussowitsch PetscCall(MatAXPY(MatsFwdSensipTemp[i], 1., ts->Jacprhs, SUBSET_NONZERO_PATTERN)); 71513af1a74SHong Zhang } 716922a638cSHong Zhang } 717922a638cSHong Zhang } 718922a638cSHong Zhang 71948a46eb9SPierre Jolivet for (i = 0; i < s; i++) PetscCall(MatAXPY(ts->mat_sensip, h * b[i], rk->MatsFwdSensipTemp[i], SAME_NONZERO_PATTERN)); 720922a638cSHong Zhang rk->status = TS_STEP_COMPLETE; 7213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 722922a638cSHong Zhang } 723922a638cSHong Zhang 724d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSForwardGetStages_RK(TS ts, PetscInt *ns, Mat **stagesensip) 725d71ae5a4SJacob Faibussowitsch { 726922a638cSHong Zhang TS_RK *rk = (TS_RK *)ts->data; 727922a638cSHong Zhang RKTableau tab = rk->tableau; 728922a638cSHong Zhang 729922a638cSHong Zhang PetscFunctionBegin; 730922a638cSHong Zhang if (ns) *ns = tab->s; 731922a638cSHong Zhang if (stagesensip) *stagesensip = rk->MatsFwdStageSensip; 7323ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 733922a638cSHong Zhang } 734922a638cSHong Zhang 735d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSForwardSetUp_RK(TS ts) 736d71ae5a4SJacob Faibussowitsch { 737922a638cSHong Zhang TS_RK *rk = (TS_RK *)ts->data; 738922a638cSHong Zhang RKTableau tab = rk->tableau; 739922a638cSHong Zhang PetscInt i; 740922a638cSHong Zhang 741922a638cSHong Zhang PetscFunctionBegin; 742922a638cSHong Zhang /* backup sensitivity results for roll-backs */ 7439566063dSJacob Faibussowitsch PetscCall(MatDuplicate(ts->mat_sensip, MAT_DO_NOT_COPY_VALUES, &rk->MatFwdSensip0)); 744922a638cSHong Zhang 7459566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(tab->s, &rk->MatsFwdStageSensip)); 7469566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(tab->s, &rk->MatsFwdSensipTemp)); 747922a638cSHong Zhang for (i = 0; i < tab->s; i++) { 7489566063dSJacob Faibussowitsch PetscCall(MatDuplicate(ts->mat_sensip, MAT_DO_NOT_COPY_VALUES, &rk->MatsFwdStageSensip[i])); 7499566063dSJacob Faibussowitsch PetscCall(MatDuplicate(ts->mat_sensip, MAT_DO_NOT_COPY_VALUES, &rk->MatsFwdSensipTemp[i])); 750922a638cSHong Zhang } 7519566063dSJacob Faibussowitsch PetscCall(VecDuplicate(ts->vec_sol, &rk->VecDeltaFwdSensipCol)); 7523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 753922a638cSHong Zhang } 754922a638cSHong Zhang 755d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSForwardReset_RK(TS ts) 756d71ae5a4SJacob Faibussowitsch { 757922a638cSHong Zhang TS_RK *rk = (TS_RK *)ts->data; 758922a638cSHong Zhang RKTableau tab = rk->tableau; 759922a638cSHong Zhang PetscInt i; 760922a638cSHong Zhang 761922a638cSHong Zhang PetscFunctionBegin; 7629566063dSJacob Faibussowitsch PetscCall(MatDestroy(&rk->MatFwdSensip0)); 763922a638cSHong Zhang if (rk->MatsFwdStageSensip) { 76448a46eb9SPierre Jolivet for (i = 0; i < tab->s; i++) PetscCall(MatDestroy(&rk->MatsFwdStageSensip[i])); 7659566063dSJacob Faibussowitsch PetscCall(PetscFree(rk->MatsFwdStageSensip)); 766922a638cSHong Zhang } 767922a638cSHong Zhang if (rk->MatsFwdSensipTemp) { 76848a46eb9SPierre Jolivet for (i = 0; i < tab->s; i++) PetscCall(MatDestroy(&rk->MatsFwdSensipTemp[i])); 7699566063dSJacob Faibussowitsch PetscCall(PetscFree(rk->MatsFwdSensipTemp)); 770922a638cSHong Zhang } 7719566063dSJacob Faibussowitsch PetscCall(VecDestroy(&rk->VecDeltaFwdSensipCol)); 7723ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 773922a638cSHong Zhang } 774922a638cSHong Zhang 775d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSStep_RK(TS ts) 776d71ae5a4SJacob Faibussowitsch { 777f68a32c8SEmil Constantinescu TS_RK *rk = (TS_RK *)ts->data; 778f68a32c8SEmil Constantinescu RKTableau tab = rk->tableau; 779f68a32c8SEmil Constantinescu const PetscInt s = tab->s; 780fecfb714SLisandro Dalcin const PetscReal *A = tab->A, *c = tab->c; 781f68a32c8SEmil Constantinescu PetscScalar *w = rk->work; 782f68a32c8SEmil Constantinescu Vec *Y = rk->Y, *YdotRHS = rk->YdotRHS; 783630f8c86SStefano Zampini PetscBool FSAL = (PetscBool)(tab->FSAL && !rk->newtableau); 784f68a32c8SEmil Constantinescu TSAdapt adapt; 785fecfb714SLisandro Dalcin PetscInt i, j; 786be5899b3SLisandro Dalcin PetscInt rejections = 0; 787be5899b3SLisandro Dalcin PetscBool stageok, accept = PETSC_TRUE; 788be5899b3SLisandro Dalcin PetscReal next_time_step = ts->time_step; 789f68a32c8SEmil Constantinescu 790f68a32c8SEmil Constantinescu PetscFunctionBegin; 791d1905564SLisandro Dalcin if (ts->steprollback || ts->steprestart) FSAL = PETSC_FALSE; 7929566063dSJacob Faibussowitsch if (FSAL) PetscCall(VecCopy(YdotRHS[s - 1], YdotRHS[0])); 793630f8c86SStefano Zampini rk->newtableau = PETSC_FALSE; 794d1905564SLisandro Dalcin 795f68a32c8SEmil Constantinescu rk->status = TS_STEP_INCOMPLETE; 796be5899b3SLisandro Dalcin while (!ts->reason && rk->status != TS_STEP_COMPLETE) { 797be5899b3SLisandro Dalcin PetscReal t = ts->ptime; 798f68a32c8SEmil Constantinescu PetscReal h = ts->time_step; 799f68a32c8SEmil Constantinescu for (i = 0; i < s; i++) { 8009be3e283SDebojyoti Ghosh rk->stage_time = t + h * c[i]; 8019566063dSJacob Faibussowitsch PetscCall(TSPreStage(ts, rk->stage_time)); 8029566063dSJacob Faibussowitsch PetscCall(VecCopy(ts->vec_sol, Y[i])); 803f68a32c8SEmil Constantinescu for (j = 0; j < i; j++) w[j] = h * A[i * s + j]; 8049566063dSJacob Faibussowitsch PetscCall(VecMAXPY(Y[i], i, w, YdotRHS)); 8059566063dSJacob Faibussowitsch PetscCall(TSPostStage(ts, rk->stage_time, i, Y)); 8069566063dSJacob Faibussowitsch PetscCall(TSGetAdapt(ts, &adapt)); 8079566063dSJacob Faibussowitsch PetscCall(TSAdaptCheckStage(adapt, ts, rk->stage_time, Y[i], &stageok)); 808fecfb714SLisandro Dalcin if (!stageok) goto reject_step; 8098f738a7cSLisandro Dalcin if (FSAL && !i) continue; 8109566063dSJacob Faibussowitsch PetscCall(TSComputeRHSFunction(ts, t + h * c[i], Y[i], YdotRHS[i])); 811f68a32c8SEmil Constantinescu } 812be5899b3SLisandro Dalcin 813be5899b3SLisandro Dalcin rk->status = TS_STEP_INCOMPLETE; 8149566063dSJacob Faibussowitsch PetscCall(TSEvaluateStep(ts, tab->order, ts->vec_sol, NULL)); 815f68a32c8SEmil Constantinescu rk->status = TS_STEP_PENDING; 8169566063dSJacob Faibussowitsch PetscCall(TSGetAdapt(ts, &adapt)); 8179566063dSJacob Faibussowitsch PetscCall(TSAdaptCandidatesClear(adapt)); 8189566063dSJacob Faibussowitsch PetscCall(TSAdaptCandidateAdd(adapt, tab->name, tab->order, 1, tab->ccfl, (PetscReal)tab->s, PETSC_TRUE)); 8199566063dSJacob Faibussowitsch PetscCall(TSAdaptChoose(adapt, ts, ts->time_step, NULL, &next_time_step, &accept)); 820be5899b3SLisandro Dalcin rk->status = accept ? TS_STEP_COMPLETE : TS_STEP_INCOMPLETE; 821be5899b3SLisandro Dalcin if (!accept) { /* Roll back the current step */ 8229566063dSJacob Faibussowitsch PetscCall(TSRollBack_RK(ts)); 823be5899b3SLisandro Dalcin ts->time_step = next_time_step; 824be5899b3SLisandro Dalcin goto reject_step; 825be5899b3SLisandro Dalcin } 826be5899b3SLisandro Dalcin 8270f7a1166SHong Zhang if (ts->costintegralfwd) { /* Save the info for the later use in cost integral evaluation */ 8280f7a1166SHong Zhang rk->ptime = ts->ptime; 8290f7a1166SHong Zhang rk->time_step = ts->time_step; 830493ed95fSHong Zhang } 831be5899b3SLisandro Dalcin 832f68a32c8SEmil Constantinescu ts->ptime += ts->time_step; 833f68a32c8SEmil Constantinescu ts->time_step = next_time_step; 834f68a32c8SEmil Constantinescu break; 835be5899b3SLisandro Dalcin 836be5899b3SLisandro Dalcin reject_step: 8379371c9d4SSatish Balay ts->reject++; 8389371c9d4SSatish Balay accept = PETSC_FALSE; 839be5899b3SLisandro Dalcin if (!ts->reason && ++rejections > ts->max_reject && ts->max_reject >= 0) { 840be5899b3SLisandro Dalcin ts->reason = TS_DIVERGED_STEP_REJECTED; 84163a3b9bcSJacob Faibussowitsch PetscCall(PetscInfo(ts, "Step=%" PetscInt_FMT ", step rejections %" PetscInt_FMT " greater than current TS allowed, stopping solve\n", ts->steps, rejections)); 842f68a32c8SEmil Constantinescu } 843f68a32c8SEmil Constantinescu } 8443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 845e4dd521cSBarry Smith } 846e4dd521cSBarry Smith 847d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSAdjointSetUp_RK(TS ts) 848d71ae5a4SJacob Faibussowitsch { 849f6a906c0SBarry Smith TS_RK *rk = (TS_RK *)ts->data; 850be5899b3SLisandro Dalcin RKTableau tab = rk->tableau; 851be5899b3SLisandro Dalcin PetscInt s = tab->s; 852f6a906c0SBarry Smith 853f6a906c0SBarry Smith PetscFunctionBegin; 8543ba16761SJacob Faibussowitsch if (ts->adjointsetupcalled++) PetscFunctionReturn(PETSC_SUCCESS); 8559566063dSJacob Faibussowitsch PetscCall(VecDuplicateVecs(ts->vecs_sensi[0], s * ts->numcost, &rk->VecsDeltaLam)); 8569566063dSJacob Faibussowitsch PetscCall(VecDuplicateVecs(ts->vecs_sensi[0], ts->numcost, &rk->VecsSensiTemp)); 85748a46eb9SPierre Jolivet if (ts->vecs_sensip) PetscCall(VecDuplicate(ts->vecs_sensip[0], &rk->VecDeltaMu)); 85813af1a74SHong Zhang if (ts->vecs_sensi2) { 8599566063dSJacob Faibussowitsch PetscCall(VecDuplicateVecs(ts->vecs_sensi[0], s * ts->numcost, &rk->VecsDeltaLam2)); 8609566063dSJacob Faibussowitsch PetscCall(VecDuplicateVecs(ts->vecs_sensi2[0], ts->numcost, &rk->VecsSensi2Temp)); 86113af1a74SHong Zhang } 86248a46eb9SPierre Jolivet if (ts->vecs_sensi2p) PetscCall(VecDuplicate(ts->vecs_sensi2p[0], &rk->VecDeltaMu2)); 8633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 864f6a906c0SBarry Smith } 865f6a906c0SBarry Smith 86635f5172aSHong Zhang /* 86735f5172aSHong Zhang Assumptions: 86835f5172aSHong Zhang - TSStep_RK() always evaluates the step with b, not bembed. 86935f5172aSHong Zhang */ 870d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSAdjointStep_RK(TS ts) 871d71ae5a4SJacob Faibussowitsch { 872c235aa8dSHong Zhang TS_RK *rk = (TS_RK *)ts->data; 873cd4cee2dSHong Zhang TS quadts = ts->quadraturets; 874c235aa8dSHong Zhang RKTableau tab = rk->tableau; 8753ca0882eSHong Zhang Mat J, Jpre, Jquad; 876c235aa8dSHong Zhang const PetscInt s = tab->s; 877c235aa8dSHong Zhang const PetscReal *A = tab->A, *b = tab->b, *c = tab->c; 87813af1a74SHong Zhang PetscScalar *w = rk->work, *xarr; 8792e7b7f96SHong Zhang Vec *Y = rk->Y, *VecsDeltaLam = rk->VecsDeltaLam, VecDeltaMu = rk->VecDeltaMu, *VecsSensiTemp = rk->VecsSensiTemp; 88013af1a74SHong Zhang Vec *VecsDeltaLam2 = rk->VecsDeltaLam2, VecDeltaMu2 = rk->VecDeltaMu2, *VecsSensi2Temp = rk->VecsSensi2Temp; 881cd4cee2dSHong Zhang Vec VecDRDUTransCol = ts->vec_drdu_col, VecDRDPTransCol = ts->vec_drdp_col; 882b18ea86cSHong Zhang PetscInt i, j, nadj; 8833d3eaba7SBarry Smith PetscReal t = ts->ptime; 8843ca0882eSHong Zhang PetscReal h = ts->time_step; 885c235aa8dSHong Zhang 886d2daff3dSHong Zhang PetscFunctionBegin; 887c235aa8dSHong Zhang rk->status = TS_STEP_INCOMPLETE; 8883389c7d9SStefano Zampini 8899566063dSJacob Faibussowitsch PetscCall(TSGetRHSJacobian(ts, &J, &Jpre, NULL, NULL)); 89048a46eb9SPierre Jolivet if (quadts) PetscCall(TSGetRHSJacobian(quadts, &Jquad, NULL, NULL, NULL)); 8912e7b7f96SHong Zhang for (i = s - 1; i >= 0; i--) { 8926a1e4597SHong Zhang if (tab->FSAL && i == s - 1) { 8936a1e4597SHong Zhang /* VecsDeltaLam[nadj*s+s-1] are initialized with zeros and the values never change.*/ 8946a1e4597SHong Zhang continue; 8956a1e4597SHong Zhang } 8963ca0882eSHong Zhang rk->stage_time = t + h * (1.0 - c[i]); 8979566063dSJacob Faibussowitsch PetscCall(TSComputeSNESJacobian(ts, Y[i], J, Jpre)); 8989371c9d4SSatish Balay if (quadts) { PetscCall(TSComputeRHSJacobian(quadts, rk->stage_time, Y[i], Jquad, Jquad)); /* get r_u^T */ } 8993389c7d9SStefano Zampini if (ts->vecs_sensip) { 9009566063dSJacob Faibussowitsch PetscCall(TSComputeRHSJacobianP(ts, rk->stage_time, Y[i], ts->Jacprhs)); /* get f_p */ 9019371c9d4SSatish Balay if (quadts) { PetscCall(TSComputeRHSJacobianP(quadts, rk->stage_time, Y[i], quadts->Jacprhs)); /* get f_p for the quadrature */ } 90235f5172aSHong Zhang } 9033389c7d9SStefano Zampini 90435f5172aSHong Zhang if (b[i]) { 90535f5172aSHong Zhang for (j = i + 1; j < s; j++) w[j - i - 1] = A[j * s + i] / b[i]; /* coefficients for computing VecsSensiTemp */ 90635f5172aSHong Zhang } else { 90735f5172aSHong Zhang for (j = i + 1; j < s; j++) w[j - i - 1] = A[j * s + i]; /* coefficients for computing VecsSensiTemp */ 90835f5172aSHong Zhang } 9092e7b7f96SHong Zhang 9102e7b7f96SHong Zhang for (nadj = 0; nadj < ts->numcost; nadj++) { 9113389c7d9SStefano Zampini /* Stage values of lambda */ 91235f5172aSHong Zhang if (b[i]) { 91335f5172aSHong Zhang /* lambda_{n+1} + \sum_{j=i+1}^s a_{ji}/b[i]*lambda_{s,j} */ 9149566063dSJacob Faibussowitsch PetscCall(VecCopy(ts->vecs_sensi[nadj], VecsSensiTemp[nadj])); /* VecDeltaLam is an vec array of size s by numcost */ 9159566063dSJacob Faibussowitsch PetscCall(VecMAXPY(VecsSensiTemp[nadj], s - i - 1, w, &VecsDeltaLam[nadj * s + i + 1])); 9169566063dSJacob Faibussowitsch PetscCall(MatMultTranspose(J, VecsSensiTemp[nadj], VecsDeltaLam[nadj * s + i])); /* VecsSensiTemp will be reused by 2nd-order adjoint */ 9179566063dSJacob Faibussowitsch PetscCall(VecScale(VecsDeltaLam[nadj * s + i], -h * b[i])); 91835f5172aSHong Zhang if (quadts) { 9199566063dSJacob Faibussowitsch PetscCall(MatDenseGetColumn(Jquad, nadj, &xarr)); 9209566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(VecDRDUTransCol, xarr)); 9219566063dSJacob Faibussowitsch PetscCall(VecAXPY(VecsDeltaLam[nadj * s + i], -h * b[i], VecDRDUTransCol)); 9229566063dSJacob Faibussowitsch PetscCall(VecResetArray(VecDRDUTransCol)); 9239566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreColumn(Jquad, &xarr)); 924cd4cee2dSHong Zhang } 9253389c7d9SStefano Zampini } else { 9266a1e4597SHong Zhang /* \sum_{j=i+1}^s a_{ji}*lambda_{s,j} */ 9279566063dSJacob Faibussowitsch PetscCall(VecSet(VecsSensiTemp[nadj], 0)); 9289566063dSJacob Faibussowitsch PetscCall(VecMAXPY(VecsSensiTemp[nadj], s - i - 1, w, &VecsDeltaLam[nadj * s + i + 1])); 9299566063dSJacob Faibussowitsch PetscCall(MatMultTranspose(J, VecsSensiTemp[nadj], VecsDeltaLam[nadj * s + i])); 9309566063dSJacob Faibussowitsch PetscCall(VecScale(VecsDeltaLam[nadj * s + i], -h)); 9313389c7d9SStefano Zampini } 9326497ce14SHong Zhang 933ad8e2604SHong Zhang /* Stage values of mu */ 9346497ce14SHong Zhang if (ts->vecs_sensip) { 93535f5172aSHong Zhang if (b[i]) { 9369566063dSJacob Faibussowitsch PetscCall(MatMultTranspose(ts->Jacprhs, VecsSensiTemp[nadj], VecDeltaMu)); 9379566063dSJacob Faibussowitsch PetscCall(VecScale(VecDeltaMu, -h * b[i])); 93835f5172aSHong Zhang if (quadts) { 9399566063dSJacob Faibussowitsch PetscCall(MatDenseGetColumn(quadts->Jacprhs, nadj, &xarr)); 9409566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(VecDRDPTransCol, xarr)); 9419566063dSJacob Faibussowitsch PetscCall(VecAXPY(VecDeltaMu, -h * b[i], VecDRDPTransCol)); 9429566063dSJacob Faibussowitsch PetscCall(VecResetArray(VecDRDPTransCol)); 9439566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreColumn(quadts->Jacprhs, &xarr)); 944493ed95fSHong Zhang } 94535f5172aSHong Zhang } else { 9469566063dSJacob Faibussowitsch PetscCall(VecScale(VecDeltaMu, -h)); 94735f5172aSHong Zhang } 9489566063dSJacob Faibussowitsch PetscCall(VecAXPY(ts->vecs_sensip[nadj], 1., VecDeltaMu)); /* update sensip for each stage */ 949ad8e2604SHong Zhang } 950c235aa8dSHong Zhang } 95113af1a74SHong Zhang 95213af1a74SHong Zhang if (ts->vecs_sensi2 && ts->forward_solve) { /* 2nd-order adjoint, TLM mode has to be turned on */ 95313af1a74SHong Zhang /* Get w1 at t_{n+1} from TLM matrix */ 9549566063dSJacob Faibussowitsch PetscCall(MatDenseGetColumn(rk->MatsFwdStageSensip[i], 0, &xarr)); 9559566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(ts->vec_sensip_col, xarr)); 95613af1a74SHong Zhang /* lambda_s^T F_UU w_1 */ 9579566063dSJacob Faibussowitsch PetscCall(TSComputeRHSHessianProductFunctionUU(ts, rk->stage_time, Y[i], VecsSensiTemp, ts->vec_sensip_col, ts->vecs_guu)); 95835f5172aSHong Zhang if (quadts) { 95935f5172aSHong Zhang /* R_UU w_1 */ 9609566063dSJacob Faibussowitsch PetscCall(TSComputeRHSHessianProductFunctionUU(quadts, rk->stage_time, Y[i], NULL, ts->vec_sensip_col, ts->vecs_guu)); 96135f5172aSHong Zhang } 96235f5172aSHong Zhang if (ts->vecs_sensip) { 96313af1a74SHong Zhang /* lambda_s^T F_UP w_2 */ 9649566063dSJacob Faibussowitsch PetscCall(TSComputeRHSHessianProductFunctionUP(ts, rk->stage_time, Y[i], VecsSensiTemp, ts->vec_dir, ts->vecs_gup)); 96535f5172aSHong Zhang if (quadts) { 96635f5172aSHong Zhang /* R_UP w_2 */ 9679566063dSJacob Faibussowitsch PetscCall(TSComputeRHSHessianProductFunctionUP(quadts, rk->stage_time, Y[i], NULL, ts->vec_sensip_col, ts->vecs_gup)); 96835f5172aSHong Zhang } 96935f5172aSHong Zhang } 97013af1a74SHong Zhang if (ts->vecs_sensi2p) { 97113af1a74SHong Zhang /* lambda_s^T F_PU w_1 */ 9729566063dSJacob Faibussowitsch PetscCall(TSComputeRHSHessianProductFunctionPU(ts, rk->stage_time, Y[i], VecsSensiTemp, ts->vec_sensip_col, ts->vecs_gpu)); 97335f5172aSHong Zhang /* lambda_s^T F_PP w_2 */ 9749566063dSJacob Faibussowitsch PetscCall(TSComputeRHSHessianProductFunctionPP(ts, rk->stage_time, Y[i], VecsSensiTemp, ts->vec_dir, ts->vecs_gpp)); 97535f5172aSHong Zhang if (b[i] && quadts) { 97635f5172aSHong Zhang /* R_PU w_1 */ 9779566063dSJacob Faibussowitsch PetscCall(TSComputeRHSHessianProductFunctionPU(quadts, rk->stage_time, Y[i], NULL, ts->vec_sensip_col, ts->vecs_gpu)); 97835f5172aSHong Zhang /* R_PP w_2 */ 9799566063dSJacob Faibussowitsch PetscCall(TSComputeRHSHessianProductFunctionPP(quadts, rk->stage_time, Y[i], NULL, ts->vec_dir, ts->vecs_gpp)); 98035f5172aSHong Zhang } 98113af1a74SHong Zhang } 9829566063dSJacob Faibussowitsch PetscCall(VecResetArray(ts->vec_sensip_col)); 9839566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreColumn(rk->MatsFwdStageSensip[i], &xarr)); 98413af1a74SHong Zhang 98513af1a74SHong Zhang for (nadj = 0; nadj < ts->numcost; nadj++) { 98613af1a74SHong Zhang /* Stage values of lambda */ 98735f5172aSHong Zhang if (b[i]) { 98835f5172aSHong Zhang /* J_i^T*(Lambda_{n+1}+\sum_{j=i+1}^s a_{ji}/b_i*Lambda_{s,j} */ 9899566063dSJacob Faibussowitsch PetscCall(VecCopy(ts->vecs_sensi2[nadj], VecsSensi2Temp[nadj])); 9909566063dSJacob Faibussowitsch PetscCall(VecMAXPY(VecsSensi2Temp[nadj], s - i - 1, w, &VecsDeltaLam2[nadj * s + i + 1])); 9919566063dSJacob Faibussowitsch PetscCall(MatMultTranspose(J, VecsSensi2Temp[nadj], VecsDeltaLam2[nadj * s + i])); 9929566063dSJacob Faibussowitsch PetscCall(VecScale(VecsDeltaLam2[nadj * s + i], -h * b[i])); 9939566063dSJacob Faibussowitsch PetscCall(VecAXPY(VecsDeltaLam2[nadj * s + i], -h * b[i], ts->vecs_guu[nadj])); 99448a46eb9SPierre Jolivet if (ts->vecs_sensip) PetscCall(VecAXPY(VecsDeltaLam2[nadj * s + i], -h * b[i], ts->vecs_gup[nadj])); 99513af1a74SHong Zhang } else { 99635f5172aSHong Zhang /* \sum_{j=i+1}^s a_{ji}*Lambda_{s,j} */ 9979566063dSJacob Faibussowitsch PetscCall(VecSet(VecsDeltaLam2[nadj * s + i], 0)); 9989566063dSJacob Faibussowitsch PetscCall(VecMAXPY(VecsSensi2Temp[nadj], s - i - 1, w, &VecsDeltaLam2[nadj * s + i + 1])); 9999566063dSJacob Faibussowitsch PetscCall(MatMultTranspose(J, VecsSensi2Temp[nadj], VecsDeltaLam2[nadj * s + i])); 10009566063dSJacob Faibussowitsch PetscCall(VecScale(VecsDeltaLam2[nadj * s + i], -h)); 10019566063dSJacob Faibussowitsch PetscCall(VecAXPY(VecsDeltaLam2[nadj * s + i], -h, ts->vecs_guu[nadj])); 100248a46eb9SPierre Jolivet if (ts->vecs_sensip) PetscCall(VecAXPY(VecsDeltaLam2[nadj * s + i], -h, ts->vecs_gup[nadj])); 100335f5172aSHong Zhang } 100435f5172aSHong Zhang if (ts->vecs_sensi2p) { /* 2nd-order adjoint for parameters */ 10059566063dSJacob Faibussowitsch PetscCall(MatMultTranspose(ts->Jacprhs, VecsSensi2Temp[nadj], VecDeltaMu2)); 100635f5172aSHong Zhang if (b[i]) { 10079566063dSJacob Faibussowitsch PetscCall(VecScale(VecDeltaMu2, -h * b[i])); 10089566063dSJacob Faibussowitsch PetscCall(VecAXPY(VecDeltaMu2, -h * b[i], ts->vecs_gpu[nadj])); 10099566063dSJacob Faibussowitsch PetscCall(VecAXPY(VecDeltaMu2, -h * b[i], ts->vecs_gpp[nadj])); 101013af1a74SHong Zhang } else { 10119566063dSJacob Faibussowitsch PetscCall(VecScale(VecDeltaMu2, -h)); 10129566063dSJacob Faibussowitsch PetscCall(VecAXPY(VecDeltaMu2, -h, ts->vecs_gpu[nadj])); 10139566063dSJacob Faibussowitsch PetscCall(VecAXPY(VecDeltaMu2, -h, ts->vecs_gpp[nadj])); 101413af1a74SHong Zhang } 10159566063dSJacob Faibussowitsch PetscCall(VecAXPY(ts->vecs_sensi2p[nadj], 1, VecDeltaMu2)); /* update sensi2p for each stage */ 101613af1a74SHong Zhang } 101713af1a74SHong Zhang } 101813af1a74SHong Zhang } 10196497ce14SHong Zhang } 1020c235aa8dSHong Zhang 1021c235aa8dSHong Zhang for (j = 0; j < s; j++) w[j] = 1.0; 10222e7b7f96SHong Zhang for (nadj = 0; nadj < ts->numcost; nadj++) { /* no need to do this for mu's */ 10239566063dSJacob Faibussowitsch PetscCall(VecMAXPY(ts->vecs_sensi[nadj], s, w, &VecsDeltaLam[nadj * s])); 102448a46eb9SPierre Jolivet if (ts->vecs_sensi2) PetscCall(VecMAXPY(ts->vecs_sensi2[nadj], s, w, &VecsDeltaLam2[nadj * s])); 10256497ce14SHong Zhang } 1026c235aa8dSHong Zhang rk->status = TS_STEP_COMPLETE; 10273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1028d2daff3dSHong Zhang } 1029d2daff3dSHong Zhang 1030d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSAdjointReset_RK(TS ts) 1031d71ae5a4SJacob Faibussowitsch { 103213af1a74SHong Zhang TS_RK *rk = (TS_RK *)ts->data; 103313af1a74SHong Zhang RKTableau tab = rk->tableau; 103413af1a74SHong Zhang 103513af1a74SHong Zhang PetscFunctionBegin; 10369566063dSJacob Faibussowitsch PetscCall(VecDestroyVecs(tab->s * ts->numcost, &rk->VecsDeltaLam)); 10379566063dSJacob Faibussowitsch PetscCall(VecDestroyVecs(ts->numcost, &rk->VecsSensiTemp)); 10389566063dSJacob Faibussowitsch PetscCall(VecDestroy(&rk->VecDeltaMu)); 10399566063dSJacob Faibussowitsch PetscCall(VecDestroyVecs(tab->s * ts->numcost, &rk->VecsDeltaLam2)); 10409566063dSJacob Faibussowitsch PetscCall(VecDestroy(&rk->VecDeltaMu2)); 10419566063dSJacob Faibussowitsch PetscCall(VecDestroyVecs(ts->numcost, &rk->VecsSensi2Temp)); 10423ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 104313af1a74SHong Zhang } 104413af1a74SHong Zhang 1045d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSInterpolate_RK(TS ts, PetscReal itime, Vec X) 1046d71ae5a4SJacob Faibussowitsch { 104755de54fcSHong Zhang TS_RK *rk = (TS_RK *)ts->data; 104855de54fcSHong Zhang PetscInt s = rk->tableau->s, p = rk->tableau->p, i, j; 104955de54fcSHong Zhang PetscReal h; 105055de54fcSHong Zhang PetscReal tt, t; 105155de54fcSHong Zhang PetscScalar *b; 105255de54fcSHong Zhang const PetscReal *B = rk->tableau->binterp; 105355de54fcSHong Zhang 105455de54fcSHong Zhang PetscFunctionBegin; 10553c633725SBarry Smith PetscCheck(B, PetscObjectComm((PetscObject)ts), PETSC_ERR_SUP, "TSRK %s does not have an interpolation formula", rk->tableau->name); 105655de54fcSHong Zhang 105755de54fcSHong Zhang switch (rk->status) { 105855de54fcSHong Zhang case TS_STEP_INCOMPLETE: 105955de54fcSHong Zhang case TS_STEP_PENDING: 106055de54fcSHong Zhang h = ts->time_step; 106155de54fcSHong Zhang t = (itime - ts->ptime) / h; 106255de54fcSHong Zhang break; 106355de54fcSHong Zhang case TS_STEP_COMPLETE: 106455de54fcSHong Zhang h = ts->ptime - ts->ptime_prev; 106555de54fcSHong Zhang t = (itime - ts->ptime) / h + 1; /* In the interval [0,1] */ 106655de54fcSHong Zhang break; 1067d71ae5a4SJacob Faibussowitsch default: 1068d71ae5a4SJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)ts), PETSC_ERR_PLIB, "Invalid TSStepStatus"); 106955de54fcSHong Zhang } 10709566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(s, &b)); 107155de54fcSHong Zhang for (i = 0; i < s; i++) b[i] = 0; 107255de54fcSHong Zhang for (j = 0, tt = t; j < p; j++, tt *= t) { 1073ad540459SPierre Jolivet for (i = 0; i < s; i++) b[i] += h * B[i * p + j] * tt; 107455de54fcSHong Zhang } 10759566063dSJacob Faibussowitsch PetscCall(VecCopy(rk->Y[0], X)); 10769566063dSJacob Faibussowitsch PetscCall(VecMAXPY(X, s, b, rk->YdotRHS)); 10779566063dSJacob Faibussowitsch PetscCall(PetscFree(b)); 10783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 107955de54fcSHong Zhang } 108055de54fcSHong Zhang 108155de54fcSHong Zhang /*------------------------------------------------------------*/ 108255de54fcSHong Zhang 1083d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSRKTableauReset(TS ts) 1084d71ae5a4SJacob Faibussowitsch { 1085be5899b3SLisandro Dalcin TS_RK *rk = (TS_RK *)ts->data; 1086be5899b3SLisandro Dalcin RKTableau tab = rk->tableau; 1087be5899b3SLisandro Dalcin 1088be5899b3SLisandro Dalcin PetscFunctionBegin; 10893ba16761SJacob Faibussowitsch if (!tab) PetscFunctionReturn(PETSC_SUCCESS); 10909566063dSJacob Faibussowitsch PetscCall(PetscFree(rk->work)); 10919566063dSJacob Faibussowitsch PetscCall(VecDestroyVecs(tab->s, &rk->Y)); 10929566063dSJacob Faibussowitsch PetscCall(VecDestroyVecs(tab->s, &rk->YdotRHS)); 10933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1094be5899b3SLisandro Dalcin } 1095be5899b3SLisandro Dalcin 1096d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSReset_RK(TS ts) 1097d71ae5a4SJacob Faibussowitsch { 1098e4dd521cSBarry Smith PetscFunctionBegin; 10999566063dSJacob Faibussowitsch PetscCall(TSRKTableauReset(ts)); 11000fe4d17eSHong Zhang if (ts->use_splitrhsfunction) { 1101cac4c232SBarry Smith PetscTryMethod(ts, "TSReset_RK_MultirateSplit_C", (TS), (ts)); 11020fe4d17eSHong Zhang } else { 1103cac4c232SBarry Smith PetscTryMethod(ts, "TSReset_RK_MultirateNonsplit_C", (TS), (ts)); 11040fe4d17eSHong Zhang } 11053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1106e4dd521cSBarry Smith } 1107277b19d0SLisandro Dalcin 1108d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMCoarsenHook_TSRK(DM fine, DM coarse, void *ctx) 1109d71ae5a4SJacob Faibussowitsch { 1110f68a32c8SEmil Constantinescu PetscFunctionBegin; 11113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1112f68a32c8SEmil Constantinescu } 1113f68a32c8SEmil Constantinescu 1114d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMRestrictHook_TSRK(DM fine, Mat restrct, Vec rscale, Mat inject, DM coarse, void *ctx) 1115d71ae5a4SJacob Faibussowitsch { 1116f68a32c8SEmil Constantinescu PetscFunctionBegin; 11173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1118f68a32c8SEmil Constantinescu } 1119f68a32c8SEmil Constantinescu 1120d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMSubDomainHook_TSRK(DM dm, DM subdm, void *ctx) 1121d71ae5a4SJacob Faibussowitsch { 1122f68a32c8SEmil Constantinescu PetscFunctionBegin; 11233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1124f68a32c8SEmil Constantinescu } 1125f68a32c8SEmil Constantinescu 1126d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMSubDomainRestrictHook_TSRK(DM dm, VecScatter gscat, VecScatter lscat, DM subdm, void *ctx) 1127d71ae5a4SJacob Faibussowitsch { 1128f68a32c8SEmil Constantinescu PetscFunctionBegin; 11293ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1130f68a32c8SEmil Constantinescu } 1131be5899b3SLisandro Dalcin 1132d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSRKTableauSetUp(TS ts) 1133d71ae5a4SJacob Faibussowitsch { 1134be5899b3SLisandro Dalcin TS_RK *rk = (TS_RK *)ts->data; 1135be5899b3SLisandro Dalcin RKTableau tab = rk->tableau; 1136be5899b3SLisandro Dalcin 1137be5899b3SLisandro Dalcin PetscFunctionBegin; 11389566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(tab->s, &rk->work)); 11399566063dSJacob Faibussowitsch PetscCall(VecDuplicateVecs(ts->vec_sol, tab->s, &rk->Y)); 11409566063dSJacob Faibussowitsch PetscCall(VecDuplicateVecs(ts->vec_sol, tab->s, &rk->YdotRHS)); 1141630f8c86SStefano Zampini rk->newtableau = PETSC_TRUE; 11423ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1143be5899b3SLisandro Dalcin } 1144be5899b3SLisandro Dalcin 1145d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSSetUp_RK(TS ts) 1146d71ae5a4SJacob Faibussowitsch { 1147cd4cee2dSHong Zhang TS quadts = ts->quadraturets; 1148f68a32c8SEmil Constantinescu DM dm; 1149f68a32c8SEmil Constantinescu 1150f68a32c8SEmil Constantinescu PetscFunctionBegin; 11519566063dSJacob Faibussowitsch PetscCall(TSCheckImplicitTerm(ts)); 11529566063dSJacob Faibussowitsch PetscCall(TSRKTableauSetUp(ts)); 1153cd4cee2dSHong Zhang if (quadts && ts->costintegralfwd) { 1154cd4cee2dSHong Zhang Mat Jquad; 11559566063dSJacob Faibussowitsch PetscCall(TSGetRHSJacobian(quadts, &Jquad, NULL, NULL, NULL)); 11560f7a1166SHong Zhang } 11579566063dSJacob Faibussowitsch PetscCall(TSGetDM(ts, &dm)); 11589566063dSJacob Faibussowitsch PetscCall(DMCoarsenHookAdd(dm, DMCoarsenHook_TSRK, DMRestrictHook_TSRK, ts)); 11599566063dSJacob Faibussowitsch PetscCall(DMSubDomainHookAdd(dm, DMSubDomainHook_TSRK, DMSubDomainRestrictHook_TSRK, ts)); 11600fe4d17eSHong Zhang if (ts->use_splitrhsfunction) { 1161cac4c232SBarry Smith PetscTryMethod(ts, "TSSetUp_RK_MultirateSplit_C", (TS), (ts)); 11620fe4d17eSHong Zhang } else { 1163cac4c232SBarry Smith PetscTryMethod(ts, "TSSetUp_RK_MultirateNonsplit_C", (TS), (ts)); 11640fe4d17eSHong Zhang } 11653ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1166e4dd521cSBarry Smith } 1167d2daff3dSHong Zhang 1168d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSSetFromOptions_RK(TS ts, PetscOptionItems *PetscOptionsObject) 1169d71ae5a4SJacob Faibussowitsch { 1170be5899b3SLisandro Dalcin TS_RK *rk = (TS_RK *)ts->data; 1171262ff7bbSBarry Smith 1172e4dd521cSBarry Smith PetscFunctionBegin; 1173d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "RK ODE solver options"); 1174f68a32c8SEmil Constantinescu { 1175f68a32c8SEmil Constantinescu RKTableauLink link; 1176f68a32c8SEmil Constantinescu PetscInt count, choice; 11770fe4d17eSHong Zhang PetscBool flg, use_multirate = PETSC_FALSE; 1178f68a32c8SEmil Constantinescu const char **namelist; 11792c9cb062Sluzhanghpp 11809371c9d4SSatish Balay for (link = RKTableauList, count = 0; link; link = link->next, count++) 11819371c9d4SSatish Balay ; 11829566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(count, (char ***)&namelist)); 1183f68a32c8SEmil Constantinescu for (link = RKTableauList, count = 0; link; link = link->next, count++) namelist[count] = link->tab.name; 11849566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-ts_rk_multirate", "Use interpolation-based multirate RK method", "TSRKSetMultirate", rk->use_multirate, &use_multirate, &flg)); 11851baa6e33SBarry Smith if (flg) PetscCall(TSRKSetMultirate(ts, use_multirate)); 11869566063dSJacob Faibussowitsch PetscCall(PetscOptionsEList("-ts_rk_type", "Family of RK method", "TSRKSetType", (const char *const *)namelist, count, rk->tableau->name, &choice, &flg)); 11879566063dSJacob Faibussowitsch if (flg) PetscCall(TSRKSetType(ts, namelist[choice])); 11889566063dSJacob Faibussowitsch PetscCall(PetscFree(namelist)); 1189f68a32c8SEmil Constantinescu } 1190d0609cedSBarry Smith PetscOptionsHeadEnd(); 1191d0609cedSBarry Smith PetscOptionsBegin(PetscObjectComm((PetscObject)ts), NULL, "Multirate methods options", ""); 11929566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-ts_rk_dtratio", "time step ratio between slow and fast", "", rk->dtratio, &rk->dtratio, NULL)); 1193d0609cedSBarry Smith PetscOptionsEnd(); 11943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1195e4dd521cSBarry Smith } 1196e4dd521cSBarry Smith 1197d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSView_RK(TS ts, PetscViewer viewer) 1198d71ae5a4SJacob Faibussowitsch { 11995f70b478SJed Brown TS_RK *rk = (TS_RK *)ts->data; 12008370ee3bSLisandro Dalcin PetscBool iascii; 12012cdf8120Sasbjorn 1202e4dd521cSBarry Smith PetscFunctionBegin; 12039566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 12048370ee3bSLisandro Dalcin if (iascii) { 12059c334d8fSLisandro Dalcin RKTableau tab = rk->tableau; 1206f68a32c8SEmil Constantinescu TSRKType rktype; 12070f7a28cdSStefano Zampini const PetscReal *c; 12080f7a28cdSStefano Zampini PetscInt s; 1209f68a32c8SEmil Constantinescu char buf[512]; 12100f7a28cdSStefano Zampini PetscBool FSAL; 12110f7a28cdSStefano Zampini 12129566063dSJacob Faibussowitsch PetscCall(TSRKGetType(ts, &rktype)); 12139566063dSJacob Faibussowitsch PetscCall(TSRKGetTableau(ts, &s, NULL, NULL, &c, NULL, NULL, NULL, &FSAL)); 12149566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " RK type %s\n", rktype)); 121563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Order: %" PetscInt_FMT "\n", tab->order)); 12169566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " FSAL property: %s\n", FSAL ? "yes" : "no")); 12179566063dSJacob Faibussowitsch PetscCall(PetscFormatRealArray(buf, sizeof(buf), "% 8.6f", s, c)); 12189566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Abscissa c = %s\n", buf)); 12198370ee3bSLisandro Dalcin } 12203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1221f68a32c8SEmil Constantinescu } 1222f68a32c8SEmil Constantinescu 1223d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSLoad_RK(TS ts, PetscViewer viewer) 1224d71ae5a4SJacob Faibussowitsch { 12259c334d8fSLisandro Dalcin TSAdapt adapt; 1226f68a32c8SEmil Constantinescu 1227f68a32c8SEmil Constantinescu PetscFunctionBegin; 12289566063dSJacob Faibussowitsch PetscCall(TSGetAdapt(ts, &adapt)); 12299566063dSJacob Faibussowitsch PetscCall(TSAdaptLoad(adapt, viewer)); 12303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1231f68a32c8SEmil Constantinescu } 1232f68a32c8SEmil Constantinescu 12332ea87ba9SLisandro Dalcin /*@ 1234bcf0153eSBarry Smith TSRKGetOrder - Get the order of the `TSRK` scheme 12352ea87ba9SLisandro Dalcin 123620f4b53cSBarry Smith Not Collective 12372ea87ba9SLisandro Dalcin 12382ea87ba9SLisandro Dalcin Input Parameter: 12392ea87ba9SLisandro Dalcin . ts - timestepping context 12402ea87ba9SLisandro Dalcin 12412ea87ba9SLisandro Dalcin Output Parameter: 1242bcf0153eSBarry Smith . order - order of `TSRK` scheme 12432ea87ba9SLisandro Dalcin 12442ea87ba9SLisandro Dalcin Level: intermediate 12452ea87ba9SLisandro Dalcin 12461cc06b55SBarry Smith .seealso: [](ch_ts), `TSRK`, `TSRKGetType()` 12472ea87ba9SLisandro Dalcin @*/ 1248d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRKGetOrder(TS ts, PetscInt *order) 1249d71ae5a4SJacob Faibussowitsch { 12502ea87ba9SLisandro Dalcin PetscFunctionBegin; 12512ea87ba9SLisandro Dalcin PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 12524f572ea9SToby Isaac PetscAssertPointer(order, 2); 1253cac4c232SBarry Smith PetscUseMethod(ts, "TSRKGetOrder_C", (TS, PetscInt *), (ts, order)); 12543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12552ea87ba9SLisandro Dalcin } 12562ea87ba9SLisandro Dalcin 1257f68a32c8SEmil Constantinescu /*@C 1258bcf0153eSBarry Smith TSRKSetType - Set the type of the `TSRK` scheme 1259f68a32c8SEmil Constantinescu 126020f4b53cSBarry Smith Logically Collective 1261f68a32c8SEmil Constantinescu 1262d8d19677SJose E. Roman Input Parameters: 1263f68a32c8SEmil Constantinescu + ts - timestepping context 1264bcf0153eSBarry Smith - rktype - type of `TSRK` scheme 1265f68a32c8SEmil Constantinescu 1266bcf0153eSBarry Smith Options Database Key: 12679bd3e852SBarry Smith . -ts_rk_type - <1fe,2a,3,3bs,4,5f,5dp,5bs> 1268287c2655SBarry Smith 1269f68a32c8SEmil Constantinescu Level: intermediate 1270f68a32c8SEmil Constantinescu 12711cc06b55SBarry Smith .seealso: [](ch_ts), `TSRKGetType()`, `TSRK`, `TSRKType`, `TSRK1FE`, `TSRK2A`, `TSRK2B`, `TSRK3`, `TSRK3BS`, `TSRK4`, `TSRK5F`, `TSRK5DP`, `TSRK5BS`, `TSRK6VR`, `TSRK7VR`, `TSRK8VR` 1272f68a32c8SEmil Constantinescu @*/ 1273d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRKSetType(TS ts, TSRKType rktype) 1274d71ae5a4SJacob Faibussowitsch { 1275f68a32c8SEmil Constantinescu PetscFunctionBegin; 1276f68a32c8SEmil Constantinescu PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 12774f572ea9SToby Isaac PetscAssertPointer(rktype, 2); 1278cac4c232SBarry Smith PetscTryMethod(ts, "TSRKSetType_C", (TS, TSRKType), (ts, rktype)); 12793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1280f68a32c8SEmil Constantinescu } 1281f68a32c8SEmil Constantinescu 1282f68a32c8SEmil Constantinescu /*@C 1283bcf0153eSBarry Smith TSRKGetType - Get the type of `TSRK` scheme 1284f68a32c8SEmil Constantinescu 128520f4b53cSBarry Smith Not Collective 1286f68a32c8SEmil Constantinescu 1287f68a32c8SEmil Constantinescu Input Parameter: 1288f68a32c8SEmil Constantinescu . ts - timestepping context 1289f68a32c8SEmil Constantinescu 1290f68a32c8SEmil Constantinescu Output Parameter: 1291bcf0153eSBarry Smith . rktype - type of `TSRK`-scheme 1292f68a32c8SEmil Constantinescu 1293f68a32c8SEmil Constantinescu Level: intermediate 1294f68a32c8SEmil Constantinescu 12951cc06b55SBarry Smith .seealso: [](ch_ts), `TSRKSetType()` 1296f68a32c8SEmil Constantinescu @*/ 1297d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRKGetType(TS ts, TSRKType *rktype) 1298d71ae5a4SJacob Faibussowitsch { 1299f68a32c8SEmil Constantinescu PetscFunctionBegin; 1300f68a32c8SEmil Constantinescu PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 1301cac4c232SBarry Smith PetscUseMethod(ts, "TSRKGetType_C", (TS, TSRKType *), (ts, rktype)); 13023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1303f68a32c8SEmil Constantinescu } 1304f68a32c8SEmil Constantinescu 1305d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSRKGetOrder_RK(TS ts, PetscInt *order) 1306d71ae5a4SJacob Faibussowitsch { 13072ea87ba9SLisandro Dalcin TS_RK *rk = (TS_RK *)ts->data; 13082ea87ba9SLisandro Dalcin 13092ea87ba9SLisandro Dalcin PetscFunctionBegin; 13102ea87ba9SLisandro Dalcin *order = rk->tableau->order; 13113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 13122ea87ba9SLisandro Dalcin } 13132ea87ba9SLisandro Dalcin 1314d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSRKGetType_RK(TS ts, TSRKType *rktype) 1315d71ae5a4SJacob Faibussowitsch { 1316f68a32c8SEmil Constantinescu TS_RK *rk = (TS_RK *)ts->data; 1317f68a32c8SEmil Constantinescu 1318f68a32c8SEmil Constantinescu PetscFunctionBegin; 1319f68a32c8SEmil Constantinescu *rktype = rk->tableau->name; 13203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1321f68a32c8SEmil Constantinescu } 13222c9cb062Sluzhanghpp 1323d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSRKSetType_RK(TS ts, TSRKType rktype) 1324d71ae5a4SJacob Faibussowitsch { 1325f68a32c8SEmil Constantinescu TS_RK *rk = (TS_RK *)ts->data; 1326f68a32c8SEmil Constantinescu PetscBool match; 1327f68a32c8SEmil Constantinescu RKTableauLink link; 1328f68a32c8SEmil Constantinescu 1329f68a32c8SEmil Constantinescu PetscFunctionBegin; 1330f68a32c8SEmil Constantinescu if (rk->tableau) { 13319566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(rk->tableau->name, rktype, &match)); 13323ba16761SJacob Faibussowitsch if (match) PetscFunctionReturn(PETSC_SUCCESS); 1333f68a32c8SEmil Constantinescu } 1334f68a32c8SEmil Constantinescu for (link = RKTableauList; link; link = link->next) { 13359566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(link->tab.name, rktype, &match)); 1336f68a32c8SEmil Constantinescu if (match) { 13379566063dSJacob Faibussowitsch if (ts->setupcalled) PetscCall(TSRKTableauReset(ts)); 1338f68a32c8SEmil Constantinescu rk->tableau = &link->tab; 13399566063dSJacob Faibussowitsch if (ts->setupcalled) PetscCall(TSRKTableauSetUp(ts)); 13402ffb9264SLisandro Dalcin ts->default_adapt_type = rk->tableau->bembed ? TSADAPTBASIC : TSADAPTNONE; 13413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1342f68a32c8SEmil Constantinescu } 1343f68a32c8SEmil Constantinescu } 134498921bdaSJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_UNKNOWN_TYPE, "Could not find '%s'", rktype); 1345e4dd521cSBarry Smith } 1346e4dd521cSBarry Smith 1347d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSGetStages_RK(TS ts, PetscInt *ns, Vec **Y) 1348d71ae5a4SJacob Faibussowitsch { 1349ff22ae23SHong Zhang TS_RK *rk = (TS_RK *)ts->data; 1350ff22ae23SHong Zhang 1351ff22ae23SHong Zhang PetscFunctionBegin; 13520429704eSStefano Zampini if (ns) *ns = rk->tableau->s; 1353d2daff3dSHong Zhang if (Y) *Y = rk->Y; 13543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1355ff22ae23SHong Zhang } 1356ff22ae23SHong Zhang 1357d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSDestroy_RK(TS ts) 1358d71ae5a4SJacob Faibussowitsch { 1359b3a6b972SJed Brown PetscFunctionBegin; 13609566063dSJacob Faibussowitsch PetscCall(TSReset_RK(ts)); 1361b3a6b972SJed Brown if (ts->dm) { 13629566063dSJacob Faibussowitsch PetscCall(DMCoarsenHookRemove(ts->dm, DMCoarsenHook_TSRK, DMRestrictHook_TSRK, ts)); 13639566063dSJacob Faibussowitsch PetscCall(DMSubDomainHookRemove(ts->dm, DMSubDomainHook_TSRK, DMSubDomainRestrictHook_TSRK, ts)); 1364b3a6b972SJed Brown } 13659566063dSJacob Faibussowitsch PetscCall(PetscFree(ts->data)); 13669566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSRKGetOrder_C", NULL)); 13679566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSRKGetType_C", NULL)); 13689566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSRKSetType_C", NULL)); 13699566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSRKGetTableau_C", NULL)); 13709566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSRKSetMultirate_C", NULL)); 13719566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSRKGetMultirate_C", NULL)); 13722e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSSetUp_RK_MultirateSplit_C", NULL)); 13732e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSReset_RK_MultirateSplit_C", NULL)); 13742e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSSetUp_RK_MultirateNonsplit_C", NULL)); 13752e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSReset_RK_MultirateNonsplit_C", NULL)); 13763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1377b3a6b972SJed Brown } 1378ff22ae23SHong Zhang 13793ca0882eSHong Zhang /* 13803ca0882eSHong Zhang This defines the nonlinear equation that is to be solved with SNES 13813ca0882eSHong Zhang We do not need to solve the equation; we just use SNES to approximate the Jacobian 13823ca0882eSHong Zhang */ 1383d71ae5a4SJacob Faibussowitsch static PetscErrorCode SNESTSFormFunction_RK(SNES snes, Vec x, Vec y, TS ts) 1384d71ae5a4SJacob Faibussowitsch { 13853ca0882eSHong Zhang TS_RK *rk = (TS_RK *)ts->data; 13863ca0882eSHong Zhang DM dm, dmsave; 13873ca0882eSHong Zhang 13883ca0882eSHong Zhang PetscFunctionBegin; 13899566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 13903ca0882eSHong Zhang /* DM monkey-business allows user code to call TSGetDM() inside of functions evaluated on levels of FAS */ 13913ca0882eSHong Zhang dmsave = ts->dm; 13923ca0882eSHong Zhang ts->dm = dm; 13939566063dSJacob Faibussowitsch PetscCall(TSComputeRHSFunction(ts, rk->stage_time, x, y)); 13943ca0882eSHong Zhang ts->dm = dmsave; 13953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 13963ca0882eSHong Zhang } 13973ca0882eSHong Zhang 1398d71ae5a4SJacob Faibussowitsch static PetscErrorCode SNESTSFormJacobian_RK(SNES snes, Vec x, Mat A, Mat B, TS ts) 1399d71ae5a4SJacob Faibussowitsch { 14003ca0882eSHong Zhang TS_RK *rk = (TS_RK *)ts->data; 14013ca0882eSHong Zhang DM dm, dmsave; 14023ca0882eSHong Zhang 14033ca0882eSHong Zhang PetscFunctionBegin; 14049566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 14053ca0882eSHong Zhang dmsave = ts->dm; 14063ca0882eSHong Zhang ts->dm = dm; 14079566063dSJacob Faibussowitsch PetscCall(TSComputeRHSJacobian(ts, rk->stage_time, x, A, B)); 14083ca0882eSHong Zhang ts->dm = dmsave; 14093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 14103ca0882eSHong Zhang } 14113ca0882eSHong Zhang 141221052c0cSHong Zhang /*@C 1413bcf0153eSBarry Smith TSRKSetMultirate - Use the interpolation-based multirate `TSRK` method 141421052c0cSHong Zhang 141520f4b53cSBarry Smith Logically Collective 141621052c0cSHong Zhang 1417d8d19677SJose E. Roman Input Parameters: 141821052c0cSHong Zhang + ts - timestepping context 1419bcf0153eSBarry Smith - use_multirate - `PETSC_TRUE` enables the multirate `TSRK` method, sets the basic method to be RK2A and sets the ratio between slow stepsize and fast stepsize to be 2 142021052c0cSHong Zhang 1421bcf0153eSBarry Smith Options Database Key: 142221052c0cSHong Zhang . -ts_rk_multirate - <true,false> 142321052c0cSHong Zhang 142421052c0cSHong Zhang Level: intermediate 142521052c0cSHong Zhang 1426bcf0153eSBarry Smith Note: 1427da81f932SPierre Jolivet The multirate method requires interpolation. The default interpolation works for 1st- and 2nd- order RK, but not for high-order RKs except `TSRK5DP` which comes with the interpolation coefficients (binterp). 1428bcf0153eSBarry Smith 14291cc06b55SBarry Smith .seealso: [](ch_ts), `TSRK`, `TSRKGetMultirate()` 143021052c0cSHong Zhang @*/ 1431d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRKSetMultirate(TS ts, PetscBool use_multirate) 1432d71ae5a4SJacob Faibussowitsch { 14338a4be4dbSHong Zhang PetscFunctionBegin; 1434cac4c232SBarry Smith PetscTryMethod(ts, "TSRKSetMultirate_C", (TS, PetscBool), (ts, use_multirate)); 14353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 143621052c0cSHong Zhang } 143721052c0cSHong Zhang 143821052c0cSHong Zhang /*@C 1439bcf0153eSBarry Smith TSRKGetMultirate - Gets whether to use the interpolation-based multirate `TSRK` method 144021052c0cSHong Zhang 144120f4b53cSBarry Smith Not Collective 144221052c0cSHong Zhang 144321052c0cSHong Zhang Input Parameter: 144421052c0cSHong Zhang . ts - timestepping context 144521052c0cSHong Zhang 144621052c0cSHong Zhang Output Parameter: 1447bcf0153eSBarry Smith . use_multirate - `PETSC_TRUE` if the multirate RK method is enabled, `PETSC_FALSE` otherwise 144821052c0cSHong Zhang 144921052c0cSHong Zhang Level: intermediate 145021052c0cSHong Zhang 14511cc06b55SBarry Smith .seealso: [](ch_ts), `TSRK`, `TSRKSetMultirate()` 145221052c0cSHong Zhang @*/ 1453d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRKGetMultirate(TS ts, PetscBool *use_multirate) 1454d71ae5a4SJacob Faibussowitsch { 14557dbacdf2SHong Zhang PetscFunctionBegin; 1456cac4c232SBarry Smith PetscUseMethod(ts, "TSRKGetMultirate_C", (TS, PetscBool *), (ts, use_multirate)); 14573ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 145821052c0cSHong Zhang } 145921052c0cSHong Zhang 1460ebe3b25bSBarry Smith /*MC 1461f68a32c8SEmil Constantinescu TSRK - ODE and DAE solver using Runge-Kutta schemes 1462ebe3b25bSBarry Smith 1463f68a32c8SEmil Constantinescu The user should provide the right hand side of the equation 1464bcf0153eSBarry Smith using `TSSetRHSFunction()`. 1465ebe3b25bSBarry Smith 1466d41222bbSBarry Smith Level: beginner 1467d41222bbSBarry Smith 1468bcf0153eSBarry Smith Notes: 1469bcf0153eSBarry Smith The default is `TSRK3BS`, it can be changed with `TSRKSetType()` or -ts_rk_type 1470ebe3b25bSBarry Smith 14711cc06b55SBarry Smith .seealso: [](ch_ts), `TSCreate()`, `TS`, `TSRK`, `TSSetType()`, `TSRKSetType()`, `TSRKGetType()`, `TSRK2D`, `TSRK2E`, `TSRK3`, 1472bcf0153eSBarry Smith `TSRK4`, `TSRK5`, `TSRKPRSSP2`, `TSRKBPR3`, `TSRKType`, `TSRKRegister()`, `TSRKSetMultirate()`, `TSRKGetMultirate()`, `TSType` 1473ebe3b25bSBarry Smith M*/ 1474d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode TSCreate_RK(TS ts) 1475d71ae5a4SJacob Faibussowitsch { 14761566a47fSLisandro Dalcin TS_RK *rk; 1477e4dd521cSBarry Smith 1478e4dd521cSBarry Smith PetscFunctionBegin; 14799566063dSJacob Faibussowitsch PetscCall(TSRKInitializePackage()); 1480f68a32c8SEmil Constantinescu 1481f68a32c8SEmil Constantinescu ts->ops->reset = TSReset_RK; 14825f70b478SJed Brown ts->ops->destroy = TSDestroy_RK; 14835f70b478SJed Brown ts->ops->view = TSView_RK; 1484f68a32c8SEmil Constantinescu ts->ops->load = TSLoad_RK; 1485f68a32c8SEmil Constantinescu ts->ops->setup = TSSetUp_RK; 1486f68a32c8SEmil Constantinescu ts->ops->interpolate = TSInterpolate_RK; 14872c9cb062Sluzhanghpp ts->ops->step = TSStep_RK; 1488f68a32c8SEmil Constantinescu ts->ops->evaluatestep = TSEvaluateStep_RK; 1489fecfb714SLisandro Dalcin ts->ops->rollback = TSRollBack_RK; 1490f68a32c8SEmil Constantinescu ts->ops->setfromoptions = TSSetFromOptions_RK; 1491ff22ae23SHong Zhang ts->ops->getstages = TSGetStages_RK; 1492e4dd521cSBarry Smith 14933ca0882eSHong Zhang ts->ops->snesfunction = SNESTSFormFunction_RK; 14943ca0882eSHong Zhang ts->ops->snesjacobian = SNESTSFormJacobian_RK; 14950f7a1166SHong Zhang ts->ops->adjointintegral = TSAdjointCostIntegral_RK; 149613af1a74SHong Zhang ts->ops->adjointsetup = TSAdjointSetUp_RK; 149713af1a74SHong Zhang ts->ops->adjointstep = TSAdjointStep_RK; 149813af1a74SHong Zhang ts->ops->adjointreset = TSAdjointReset_RK; 14990f7a1166SHong Zhang 150013af1a74SHong Zhang ts->ops->forwardintegral = TSForwardCostIntegral_RK; 1501922a638cSHong Zhang ts->ops->forwardsetup = TSForwardSetUp_RK; 1502922a638cSHong Zhang ts->ops->forwardreset = TSForwardReset_RK; 1503922a638cSHong Zhang ts->ops->forwardstep = TSForwardStep_RK; 1504922a638cSHong Zhang ts->ops->forwardgetstages = TSForwardGetStages_RK; 1505922a638cSHong Zhang 15064dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&rk)); 15071566a47fSLisandro Dalcin ts->data = (void *)rk; 1508e4dd521cSBarry Smith 15099566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSRKGetOrder_C", TSRKGetOrder_RK)); 15109566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSRKGetType_C", TSRKGetType_RK)); 15119566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSRKSetType_C", TSRKSetType_RK)); 15129566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSRKGetTableau_C", TSRKGetTableau_RK)); 15139566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSRKSetMultirate_C", TSRKSetMultirate_RK)); 15149566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSRKGetMultirate_C", TSRKGetMultirate_RK)); 1515be5899b3SLisandro Dalcin 15169566063dSJacob Faibussowitsch PetscCall(TSRKSetType(ts, TSRKDefault)); 151790b67129SHong Zhang rk->dtratio = 1; 15183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1519e4dd521cSBarry Smith } 1520