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
711d27aa22SBarry 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
1071d27aa22SBarry 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
1191d27aa22SBarry 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.
1321d27aa22SBarry 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.
1451d27aa22SBarry 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.
1581d27aa22SBarry 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 @*/
TSRKRegisterAll(void)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 @*/
TSRKRegisterDestroy(void)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 @*/
TSRKInitializePackage(void)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 @*/
TSRKFinalizePackage(void)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
412cc4c1da9SBarry Smith Not Collective, but the same schemes should be registered on all processes on which they will be used, No Fortran Support
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 @*/
TSRKRegister(TSRKType name,PetscInt order,PetscInt s,const PetscReal A[],const PetscReal b[],const PetscReal c[],const PetscReal bembed[],PetscInt p,const PetscReal binterp[])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
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)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 @*/
TSRKGetTableau(TS ts,PetscInt * s,const PetscReal ** A,const PetscReal ** b,const PetscReal ** c,const PetscReal ** bembed,PetscInt * p,const PetscReal ** binterp,PetscBool * FSAL)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 */
TSEvaluateStep_RK(TS ts,PetscInt order,Vec X,PetscBool * done)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:
590966bd95aSPierre Jolivet PetscCheck(done, 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,
591966bd95aSPierre Jolivet tab->order, order);
592966bd95aSPierre Jolivet *done = PETSC_FALSE;
5933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
594f68a32c8SEmil Constantinescu }
595f68a32c8SEmil Constantinescu
TSForwardCostIntegral_RK(TS ts)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
TSAdjointCostIntegral_RK(TS ts)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
TSRollBack_RK(TS ts)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
TSForwardStep_RK(TS ts)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));
703fb842aefSJose E. Roman PetscCall(MatMatMult(J, rk->MatsFwdStageSensip[i], MAT_REUSE_MATRIX, PETSC_DETERMINE, &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
TSForwardGetStages_RK(TS ts,PetscInt * ns,Mat ** stagesensip)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
TSForwardSetUp_RK(TS ts)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
TSForwardReset_RK(TS ts)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
TSStep_RK(TS ts)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
TSAdjointSetUp_RK(TS ts)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;
854371d2eb7SMartin Diehl if (ts->adjointsetupcalled) PetscFunctionReturn(PETSC_SUCCESS);
855371d2eb7SMartin Diehl ts->adjointsetupcalled = PETSC_TRUE;
8569566063dSJacob Faibussowitsch PetscCall(VecDuplicateVecs(ts->vecs_sensi[0], s * ts->numcost, &rk->VecsDeltaLam));
8579566063dSJacob Faibussowitsch PetscCall(VecDuplicateVecs(ts->vecs_sensi[0], ts->numcost, &rk->VecsSensiTemp));
85848a46eb9SPierre Jolivet if (ts->vecs_sensip) PetscCall(VecDuplicate(ts->vecs_sensip[0], &rk->VecDeltaMu));
85913af1a74SHong Zhang if (ts->vecs_sensi2) {
8609566063dSJacob Faibussowitsch PetscCall(VecDuplicateVecs(ts->vecs_sensi[0], s * ts->numcost, &rk->VecsDeltaLam2));
8619566063dSJacob Faibussowitsch PetscCall(VecDuplicateVecs(ts->vecs_sensi2[0], ts->numcost, &rk->VecsSensi2Temp));
86213af1a74SHong Zhang }
86348a46eb9SPierre Jolivet if (ts->vecs_sensi2p) PetscCall(VecDuplicate(ts->vecs_sensi2p[0], &rk->VecDeltaMu2));
8643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
865f6a906c0SBarry Smith }
866f6a906c0SBarry Smith
86735f5172aSHong Zhang /*
86835f5172aSHong Zhang Assumptions:
86935f5172aSHong Zhang - TSStep_RK() always evaluates the step with b, not bembed.
87035f5172aSHong Zhang */
TSAdjointStep_RK(TS ts)871d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSAdjointStep_RK(TS ts)
872d71ae5a4SJacob Faibussowitsch {
873c235aa8dSHong Zhang TS_RK *rk = (TS_RK *)ts->data;
874cd4cee2dSHong Zhang TS quadts = ts->quadraturets;
875c235aa8dSHong Zhang RKTableau tab = rk->tableau;
8763ca0882eSHong Zhang Mat J, Jpre, Jquad;
877c235aa8dSHong Zhang const PetscInt s = tab->s;
878c235aa8dSHong Zhang const PetscReal *A = tab->A, *b = tab->b, *c = tab->c;
87913af1a74SHong Zhang PetscScalar *w = rk->work, *xarr;
8802e7b7f96SHong Zhang Vec *Y = rk->Y, *VecsDeltaLam = rk->VecsDeltaLam, VecDeltaMu = rk->VecDeltaMu, *VecsSensiTemp = rk->VecsSensiTemp;
88113af1a74SHong Zhang Vec *VecsDeltaLam2 = rk->VecsDeltaLam2, VecDeltaMu2 = rk->VecDeltaMu2, *VecsSensi2Temp = rk->VecsSensi2Temp;
882cd4cee2dSHong Zhang Vec VecDRDUTransCol = ts->vec_drdu_col, VecDRDPTransCol = ts->vec_drdp_col;
883b18ea86cSHong Zhang PetscInt i, j, nadj;
8843d3eaba7SBarry Smith PetscReal t = ts->ptime;
8853ca0882eSHong Zhang PetscReal h = ts->time_step;
886c235aa8dSHong Zhang
887d2daff3dSHong Zhang PetscFunctionBegin;
888c235aa8dSHong Zhang rk->status = TS_STEP_INCOMPLETE;
8893389c7d9SStefano Zampini
8909566063dSJacob Faibussowitsch PetscCall(TSGetRHSJacobian(ts, &J, &Jpre, NULL, NULL));
89148a46eb9SPierre Jolivet if (quadts) PetscCall(TSGetRHSJacobian(quadts, &Jquad, NULL, NULL, NULL));
8922e7b7f96SHong Zhang for (i = s - 1; i >= 0; i--) {
8936a1e4597SHong Zhang if (tab->FSAL && i == s - 1) {
8946a1e4597SHong Zhang /* VecsDeltaLam[nadj*s+s-1] are initialized with zeros and the values never change.*/
8956a1e4597SHong Zhang continue;
8966a1e4597SHong Zhang }
8973ca0882eSHong Zhang rk->stage_time = t + h * (1.0 - c[i]);
8989566063dSJacob Faibussowitsch PetscCall(TSComputeSNESJacobian(ts, Y[i], J, Jpre));
899ac530a7eSPierre Jolivet if (quadts) PetscCall(TSComputeRHSJacobian(quadts, rk->stage_time, Y[i], Jquad, Jquad)); /* get r_u^T */
9003389c7d9SStefano Zampini if (ts->vecs_sensip) {
9019566063dSJacob Faibussowitsch PetscCall(TSComputeRHSJacobianP(ts, rk->stage_time, Y[i], ts->Jacprhs)); /* get f_p */
902ac530a7eSPierre Jolivet if (quadts) PetscCall(TSComputeRHSJacobianP(quadts, rk->stage_time, Y[i], quadts->Jacprhs)); /* get f_p for the quadrature */
90335f5172aSHong Zhang }
9043389c7d9SStefano Zampini
90535f5172aSHong Zhang if (b[i]) {
90635f5172aSHong Zhang for (j = i + 1; j < s; j++) w[j - i - 1] = A[j * s + i] / b[i]; /* coefficients for computing VecsSensiTemp */
90735f5172aSHong Zhang } else {
90835f5172aSHong Zhang for (j = i + 1; j < s; j++) w[j - i - 1] = A[j * s + i]; /* coefficients for computing VecsSensiTemp */
90935f5172aSHong Zhang }
9102e7b7f96SHong Zhang
9112e7b7f96SHong Zhang for (nadj = 0; nadj < ts->numcost; nadj++) {
9123389c7d9SStefano Zampini /* Stage values of lambda */
91335f5172aSHong Zhang if (b[i]) {
91435f5172aSHong Zhang /* lambda_{n+1} + \sum_{j=i+1}^s a_{ji}/b[i]*lambda_{s,j} */
9159566063dSJacob Faibussowitsch PetscCall(VecCopy(ts->vecs_sensi[nadj], VecsSensiTemp[nadj])); /* VecDeltaLam is an vec array of size s by numcost */
9169566063dSJacob Faibussowitsch PetscCall(VecMAXPY(VecsSensiTemp[nadj], s - i - 1, w, &VecsDeltaLam[nadj * s + i + 1]));
9179566063dSJacob Faibussowitsch PetscCall(MatMultTranspose(J, VecsSensiTemp[nadj], VecsDeltaLam[nadj * s + i])); /* VecsSensiTemp will be reused by 2nd-order adjoint */
9189566063dSJacob Faibussowitsch PetscCall(VecScale(VecsDeltaLam[nadj * s + i], -h * b[i]));
91935f5172aSHong Zhang if (quadts) {
9209566063dSJacob Faibussowitsch PetscCall(MatDenseGetColumn(Jquad, nadj, &xarr));
9219566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(VecDRDUTransCol, xarr));
9229566063dSJacob Faibussowitsch PetscCall(VecAXPY(VecsDeltaLam[nadj * s + i], -h * b[i], VecDRDUTransCol));
9239566063dSJacob Faibussowitsch PetscCall(VecResetArray(VecDRDUTransCol));
9249566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreColumn(Jquad, &xarr));
925cd4cee2dSHong Zhang }
9263389c7d9SStefano Zampini } else {
9276a1e4597SHong Zhang /* \sum_{j=i+1}^s a_{ji}*lambda_{s,j} */
9289566063dSJacob Faibussowitsch PetscCall(VecSet(VecsSensiTemp[nadj], 0));
9299566063dSJacob Faibussowitsch PetscCall(VecMAXPY(VecsSensiTemp[nadj], s - i - 1, w, &VecsDeltaLam[nadj * s + i + 1]));
9309566063dSJacob Faibussowitsch PetscCall(MatMultTranspose(J, VecsSensiTemp[nadj], VecsDeltaLam[nadj * s + i]));
9319566063dSJacob Faibussowitsch PetscCall(VecScale(VecsDeltaLam[nadj * s + i], -h));
9323389c7d9SStefano Zampini }
9336497ce14SHong Zhang
934ad8e2604SHong Zhang /* Stage values of mu */
9356497ce14SHong Zhang if (ts->vecs_sensip) {
9369566063dSJacob Faibussowitsch PetscCall(MatMultTranspose(ts->Jacprhs, VecsSensiTemp[nadj], VecDeltaMu));
93742587f1cSHong Zhang if (b[i]) {
9389566063dSJacob Faibussowitsch PetscCall(VecScale(VecDeltaMu, -h * b[i]));
93935f5172aSHong Zhang if (quadts) {
9409566063dSJacob Faibussowitsch PetscCall(MatDenseGetColumn(quadts->Jacprhs, nadj, &xarr));
9419566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(VecDRDPTransCol, xarr));
9429566063dSJacob Faibussowitsch PetscCall(VecAXPY(VecDeltaMu, -h * b[i], VecDRDPTransCol));
9439566063dSJacob Faibussowitsch PetscCall(VecResetArray(VecDRDPTransCol));
9449566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreColumn(quadts->Jacprhs, &xarr));
945493ed95fSHong Zhang }
94635f5172aSHong Zhang } else {
9479566063dSJacob Faibussowitsch PetscCall(VecScale(VecDeltaMu, -h));
94835f5172aSHong Zhang }
9499566063dSJacob Faibussowitsch PetscCall(VecAXPY(ts->vecs_sensip[nadj], 1., VecDeltaMu)); /* update sensip for each stage */
950ad8e2604SHong Zhang }
951c235aa8dSHong Zhang }
95213af1a74SHong Zhang
95313af1a74SHong Zhang if (ts->vecs_sensi2 && ts->forward_solve) { /* 2nd-order adjoint, TLM mode has to be turned on */
95413af1a74SHong Zhang /* Get w1 at t_{n+1} from TLM matrix */
9559566063dSJacob Faibussowitsch PetscCall(MatDenseGetColumn(rk->MatsFwdStageSensip[i], 0, &xarr));
9569566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(ts->vec_sensip_col, xarr));
95713af1a74SHong Zhang /* lambda_s^T F_UU w_1 */
9589566063dSJacob Faibussowitsch PetscCall(TSComputeRHSHessianProductFunctionUU(ts, rk->stage_time, Y[i], VecsSensiTemp, ts->vec_sensip_col, ts->vecs_guu));
95935f5172aSHong Zhang if (quadts) {
96035f5172aSHong Zhang /* R_UU w_1 */
9619566063dSJacob Faibussowitsch PetscCall(TSComputeRHSHessianProductFunctionUU(quadts, rk->stage_time, Y[i], NULL, ts->vec_sensip_col, ts->vecs_guu));
96235f5172aSHong Zhang }
96335f5172aSHong Zhang if (ts->vecs_sensip) {
96413af1a74SHong Zhang /* lambda_s^T F_UP w_2 */
9659566063dSJacob Faibussowitsch PetscCall(TSComputeRHSHessianProductFunctionUP(ts, rk->stage_time, Y[i], VecsSensiTemp, ts->vec_dir, ts->vecs_gup));
96635f5172aSHong Zhang if (quadts) {
96735f5172aSHong Zhang /* R_UP w_2 */
9689566063dSJacob Faibussowitsch PetscCall(TSComputeRHSHessianProductFunctionUP(quadts, rk->stage_time, Y[i], NULL, ts->vec_sensip_col, ts->vecs_gup));
96935f5172aSHong Zhang }
97035f5172aSHong Zhang }
97113af1a74SHong Zhang if (ts->vecs_sensi2p) {
97213af1a74SHong Zhang /* lambda_s^T F_PU w_1 */
9739566063dSJacob Faibussowitsch PetscCall(TSComputeRHSHessianProductFunctionPU(ts, rk->stage_time, Y[i], VecsSensiTemp, ts->vec_sensip_col, ts->vecs_gpu));
97435f5172aSHong Zhang /* lambda_s^T F_PP w_2 */
9759566063dSJacob Faibussowitsch PetscCall(TSComputeRHSHessianProductFunctionPP(ts, rk->stage_time, Y[i], VecsSensiTemp, ts->vec_dir, ts->vecs_gpp));
97635f5172aSHong Zhang if (b[i] && quadts) {
97735f5172aSHong Zhang /* R_PU w_1 */
9789566063dSJacob Faibussowitsch PetscCall(TSComputeRHSHessianProductFunctionPU(quadts, rk->stage_time, Y[i], NULL, ts->vec_sensip_col, ts->vecs_gpu));
97935f5172aSHong Zhang /* R_PP w_2 */
9809566063dSJacob Faibussowitsch PetscCall(TSComputeRHSHessianProductFunctionPP(quadts, rk->stage_time, Y[i], NULL, ts->vec_dir, ts->vecs_gpp));
98135f5172aSHong Zhang }
98213af1a74SHong Zhang }
9839566063dSJacob Faibussowitsch PetscCall(VecResetArray(ts->vec_sensip_col));
9849566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreColumn(rk->MatsFwdStageSensip[i], &xarr));
98513af1a74SHong Zhang
98613af1a74SHong Zhang for (nadj = 0; nadj < ts->numcost; nadj++) {
98713af1a74SHong Zhang /* Stage values of lambda */
98835f5172aSHong Zhang if (b[i]) {
98935f5172aSHong Zhang /* J_i^T*(Lambda_{n+1}+\sum_{j=i+1}^s a_{ji}/b_i*Lambda_{s,j} */
9909566063dSJacob Faibussowitsch PetscCall(VecCopy(ts->vecs_sensi2[nadj], VecsSensi2Temp[nadj]));
9919566063dSJacob Faibussowitsch PetscCall(VecMAXPY(VecsSensi2Temp[nadj], s - i - 1, w, &VecsDeltaLam2[nadj * s + i + 1]));
9929566063dSJacob Faibussowitsch PetscCall(MatMultTranspose(J, VecsSensi2Temp[nadj], VecsDeltaLam2[nadj * s + i]));
9939566063dSJacob Faibussowitsch PetscCall(VecScale(VecsDeltaLam2[nadj * s + i], -h * b[i]));
9949566063dSJacob Faibussowitsch PetscCall(VecAXPY(VecsDeltaLam2[nadj * s + i], -h * b[i], ts->vecs_guu[nadj]));
99548a46eb9SPierre Jolivet if (ts->vecs_sensip) PetscCall(VecAXPY(VecsDeltaLam2[nadj * s + i], -h * b[i], ts->vecs_gup[nadj]));
99613af1a74SHong Zhang } else {
99735f5172aSHong Zhang /* \sum_{j=i+1}^s a_{ji}*Lambda_{s,j} */
9989566063dSJacob Faibussowitsch PetscCall(VecSet(VecsDeltaLam2[nadj * s + i], 0));
9999566063dSJacob Faibussowitsch PetscCall(VecMAXPY(VecsSensi2Temp[nadj], s - i - 1, w, &VecsDeltaLam2[nadj * s + i + 1]));
10009566063dSJacob Faibussowitsch PetscCall(MatMultTranspose(J, VecsSensi2Temp[nadj], VecsDeltaLam2[nadj * s + i]));
10019566063dSJacob Faibussowitsch PetscCall(VecScale(VecsDeltaLam2[nadj * s + i], -h));
10029566063dSJacob Faibussowitsch PetscCall(VecAXPY(VecsDeltaLam2[nadj * s + i], -h, ts->vecs_guu[nadj]));
100348a46eb9SPierre Jolivet if (ts->vecs_sensip) PetscCall(VecAXPY(VecsDeltaLam2[nadj * s + i], -h, ts->vecs_gup[nadj]));
100435f5172aSHong Zhang }
100535f5172aSHong Zhang if (ts->vecs_sensi2p) { /* 2nd-order adjoint for parameters */
10069566063dSJacob Faibussowitsch PetscCall(MatMultTranspose(ts->Jacprhs, VecsSensi2Temp[nadj], VecDeltaMu2));
100735f5172aSHong Zhang if (b[i]) {
10089566063dSJacob Faibussowitsch PetscCall(VecScale(VecDeltaMu2, -h * b[i]));
10099566063dSJacob Faibussowitsch PetscCall(VecAXPY(VecDeltaMu2, -h * b[i], ts->vecs_gpu[nadj]));
10109566063dSJacob Faibussowitsch PetscCall(VecAXPY(VecDeltaMu2, -h * b[i], ts->vecs_gpp[nadj]));
101113af1a74SHong Zhang } else {
10129566063dSJacob Faibussowitsch PetscCall(VecScale(VecDeltaMu2, -h));
10139566063dSJacob Faibussowitsch PetscCall(VecAXPY(VecDeltaMu2, -h, ts->vecs_gpu[nadj]));
10149566063dSJacob Faibussowitsch PetscCall(VecAXPY(VecDeltaMu2, -h, ts->vecs_gpp[nadj]));
101513af1a74SHong Zhang }
10169566063dSJacob Faibussowitsch PetscCall(VecAXPY(ts->vecs_sensi2p[nadj], 1, VecDeltaMu2)); /* update sensi2p for each stage */
101713af1a74SHong Zhang }
101813af1a74SHong Zhang }
101913af1a74SHong Zhang }
10206497ce14SHong Zhang }
1021c235aa8dSHong Zhang
1022c235aa8dSHong Zhang for (j = 0; j < s; j++) w[j] = 1.0;
10232e7b7f96SHong Zhang for (nadj = 0; nadj < ts->numcost; nadj++) { /* no need to do this for mu's */
10249566063dSJacob Faibussowitsch PetscCall(VecMAXPY(ts->vecs_sensi[nadj], s, w, &VecsDeltaLam[nadj * s]));
102548a46eb9SPierre Jolivet if (ts->vecs_sensi2) PetscCall(VecMAXPY(ts->vecs_sensi2[nadj], s, w, &VecsDeltaLam2[nadj * s]));
10266497ce14SHong Zhang }
1027c235aa8dSHong Zhang rk->status = TS_STEP_COMPLETE;
10283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1029d2daff3dSHong Zhang }
1030d2daff3dSHong Zhang
TSAdjointReset_RK(TS ts)1031d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSAdjointReset_RK(TS ts)
1032d71ae5a4SJacob Faibussowitsch {
103313af1a74SHong Zhang TS_RK *rk = (TS_RK *)ts->data;
103413af1a74SHong Zhang RKTableau tab = rk->tableau;
103513af1a74SHong Zhang
103613af1a74SHong Zhang PetscFunctionBegin;
10379566063dSJacob Faibussowitsch PetscCall(VecDestroyVecs(tab->s * ts->numcost, &rk->VecsDeltaLam));
10389566063dSJacob Faibussowitsch PetscCall(VecDestroyVecs(ts->numcost, &rk->VecsSensiTemp));
10399566063dSJacob Faibussowitsch PetscCall(VecDestroy(&rk->VecDeltaMu));
10409566063dSJacob Faibussowitsch PetscCall(VecDestroyVecs(tab->s * ts->numcost, &rk->VecsDeltaLam2));
10419566063dSJacob Faibussowitsch PetscCall(VecDestroy(&rk->VecDeltaMu2));
10429566063dSJacob Faibussowitsch PetscCall(VecDestroyVecs(ts->numcost, &rk->VecsSensi2Temp));
10433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
104413af1a74SHong Zhang }
104513af1a74SHong Zhang
TSInterpolate_RK(TS ts,PetscReal itime,Vec X)1046d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSInterpolate_RK(TS ts, PetscReal itime, Vec X)
1047d71ae5a4SJacob Faibussowitsch {
104855de54fcSHong Zhang TS_RK *rk = (TS_RK *)ts->data;
104955de54fcSHong Zhang PetscInt s = rk->tableau->s, p = rk->tableau->p, i, j;
105055de54fcSHong Zhang PetscReal h;
105155de54fcSHong Zhang PetscReal tt, t;
105255de54fcSHong Zhang PetscScalar *b;
105355de54fcSHong Zhang const PetscReal *B = rk->tableau->binterp;
105455de54fcSHong Zhang
105555de54fcSHong Zhang PetscFunctionBegin;
10563c633725SBarry Smith PetscCheck(B, PetscObjectComm((PetscObject)ts), PETSC_ERR_SUP, "TSRK %s does not have an interpolation formula", rk->tableau->name);
105755de54fcSHong Zhang
105855de54fcSHong Zhang switch (rk->status) {
105955de54fcSHong Zhang case TS_STEP_INCOMPLETE:
106055de54fcSHong Zhang case TS_STEP_PENDING:
106155de54fcSHong Zhang h = ts->time_step;
106255de54fcSHong Zhang t = (itime - ts->ptime) / h;
106355de54fcSHong Zhang break;
106455de54fcSHong Zhang case TS_STEP_COMPLETE:
106555de54fcSHong Zhang h = ts->ptime - ts->ptime_prev;
106655de54fcSHong Zhang t = (itime - ts->ptime) / h + 1; /* In the interval [0,1] */
106755de54fcSHong Zhang break;
1068d71ae5a4SJacob Faibussowitsch default:
1069d71ae5a4SJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)ts), PETSC_ERR_PLIB, "Invalid TSStepStatus");
107055de54fcSHong Zhang }
10719566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(s, &b));
107255de54fcSHong Zhang for (i = 0; i < s; i++) b[i] = 0;
107355de54fcSHong Zhang for (j = 0, tt = t; j < p; j++, tt *= t) {
1074ad540459SPierre Jolivet for (i = 0; i < s; i++) b[i] += h * B[i * p + j] * tt;
107555de54fcSHong Zhang }
10769566063dSJacob Faibussowitsch PetscCall(VecCopy(rk->Y[0], X));
10779566063dSJacob Faibussowitsch PetscCall(VecMAXPY(X, s, b, rk->YdotRHS));
10789566063dSJacob Faibussowitsch PetscCall(PetscFree(b));
10793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
108055de54fcSHong Zhang }
108155de54fcSHong Zhang
TSRKTableauReset(TS ts)1082d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSRKTableauReset(TS ts)
1083d71ae5a4SJacob Faibussowitsch {
1084be5899b3SLisandro Dalcin TS_RK *rk = (TS_RK *)ts->data;
1085be5899b3SLisandro Dalcin RKTableau tab = rk->tableau;
1086be5899b3SLisandro Dalcin
1087be5899b3SLisandro Dalcin PetscFunctionBegin;
10883ba16761SJacob Faibussowitsch if (!tab) PetscFunctionReturn(PETSC_SUCCESS);
10899566063dSJacob Faibussowitsch PetscCall(PetscFree(rk->work));
10909566063dSJacob Faibussowitsch PetscCall(VecDestroyVecs(tab->s, &rk->Y));
10919566063dSJacob Faibussowitsch PetscCall(VecDestroyVecs(tab->s, &rk->YdotRHS));
10923ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1093be5899b3SLisandro Dalcin }
1094be5899b3SLisandro Dalcin
TSReset_RK(TS ts)1095d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSReset_RK(TS ts)
1096d71ae5a4SJacob Faibussowitsch {
1097e4dd521cSBarry Smith PetscFunctionBegin;
10989566063dSJacob Faibussowitsch PetscCall(TSRKTableauReset(ts));
10990fe4d17eSHong Zhang if (ts->use_splitrhsfunction) {
1100cac4c232SBarry Smith PetscTryMethod(ts, "TSReset_RK_MultirateSplit_C", (TS), (ts));
11010fe4d17eSHong Zhang } else {
1102cac4c232SBarry Smith PetscTryMethod(ts, "TSReset_RK_MultirateNonsplit_C", (TS), (ts));
11030fe4d17eSHong Zhang }
11043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1105e4dd521cSBarry Smith }
1106277b19d0SLisandro Dalcin
DMCoarsenHook_TSRK(DM fine,DM coarse,PetscCtx ctx)1107*2a8381b2SBarry Smith static PetscErrorCode DMCoarsenHook_TSRK(DM fine, DM coarse, PetscCtx ctx)
1108d71ae5a4SJacob Faibussowitsch {
1109f68a32c8SEmil Constantinescu PetscFunctionBegin;
11103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1111f68a32c8SEmil Constantinescu }
1112f68a32c8SEmil Constantinescu
DMRestrictHook_TSRK(DM fine,Mat restrct,Vec rscale,Mat inject,DM coarse,PetscCtx ctx)1113*2a8381b2SBarry Smith static PetscErrorCode DMRestrictHook_TSRK(DM fine, Mat restrct, Vec rscale, Mat inject, DM coarse, PetscCtx ctx)
1114d71ae5a4SJacob Faibussowitsch {
1115f68a32c8SEmil Constantinescu PetscFunctionBegin;
11163ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1117f68a32c8SEmil Constantinescu }
1118f68a32c8SEmil Constantinescu
DMSubDomainHook_TSRK(DM dm,DM subdm,PetscCtx ctx)1119*2a8381b2SBarry Smith static PetscErrorCode DMSubDomainHook_TSRK(DM dm, DM subdm, PetscCtx ctx)
1120d71ae5a4SJacob Faibussowitsch {
1121f68a32c8SEmil Constantinescu PetscFunctionBegin;
11223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1123f68a32c8SEmil Constantinescu }
1124f68a32c8SEmil Constantinescu
DMSubDomainRestrictHook_TSRK(DM dm,VecScatter gscat,VecScatter lscat,DM subdm,PetscCtx ctx)1125*2a8381b2SBarry Smith static PetscErrorCode DMSubDomainRestrictHook_TSRK(DM dm, VecScatter gscat, VecScatter lscat, DM subdm, PetscCtx ctx)
1126d71ae5a4SJacob Faibussowitsch {
1127f68a32c8SEmil Constantinescu PetscFunctionBegin;
11283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1129f68a32c8SEmil Constantinescu }
1130be5899b3SLisandro Dalcin
TSRKTableauSetUp(TS ts)1131d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSRKTableauSetUp(TS ts)
1132d71ae5a4SJacob Faibussowitsch {
1133be5899b3SLisandro Dalcin TS_RK *rk = (TS_RK *)ts->data;
1134be5899b3SLisandro Dalcin RKTableau tab = rk->tableau;
1135be5899b3SLisandro Dalcin
1136be5899b3SLisandro Dalcin PetscFunctionBegin;
11379566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(tab->s, &rk->work));
11389566063dSJacob Faibussowitsch PetscCall(VecDuplicateVecs(ts->vec_sol, tab->s, &rk->Y));
11399566063dSJacob Faibussowitsch PetscCall(VecDuplicateVecs(ts->vec_sol, tab->s, &rk->YdotRHS));
1140630f8c86SStefano Zampini rk->newtableau = PETSC_TRUE;
11413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1142be5899b3SLisandro Dalcin }
1143be5899b3SLisandro Dalcin
TSSetUp_RK(TS ts)1144d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSSetUp_RK(TS ts)
1145d71ae5a4SJacob Faibussowitsch {
1146cd4cee2dSHong Zhang TS quadts = ts->quadraturets;
1147f68a32c8SEmil Constantinescu DM dm;
1148f68a32c8SEmil Constantinescu
1149f68a32c8SEmil Constantinescu PetscFunctionBegin;
11509566063dSJacob Faibussowitsch PetscCall(TSCheckImplicitTerm(ts));
11519566063dSJacob Faibussowitsch PetscCall(TSRKTableauSetUp(ts));
1152cd4cee2dSHong Zhang if (quadts && ts->costintegralfwd) {
1153cd4cee2dSHong Zhang Mat Jquad;
11549566063dSJacob Faibussowitsch PetscCall(TSGetRHSJacobian(quadts, &Jquad, NULL, NULL, NULL));
11550f7a1166SHong Zhang }
11569566063dSJacob Faibussowitsch PetscCall(TSGetDM(ts, &dm));
11579566063dSJacob Faibussowitsch PetscCall(DMCoarsenHookAdd(dm, DMCoarsenHook_TSRK, DMRestrictHook_TSRK, ts));
11589566063dSJacob Faibussowitsch PetscCall(DMSubDomainHookAdd(dm, DMSubDomainHook_TSRK, DMSubDomainRestrictHook_TSRK, ts));
11590fe4d17eSHong Zhang if (ts->use_splitrhsfunction) {
1160cac4c232SBarry Smith PetscTryMethod(ts, "TSSetUp_RK_MultirateSplit_C", (TS), (ts));
11610fe4d17eSHong Zhang } else {
1162cac4c232SBarry Smith PetscTryMethod(ts, "TSSetUp_RK_MultirateNonsplit_C", (TS), (ts));
11630fe4d17eSHong Zhang }
11643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1165e4dd521cSBarry Smith }
1166d2daff3dSHong Zhang
TSSetFromOptions_RK(TS ts,PetscOptionItems PetscOptionsObject)1167ce78bad3SBarry Smith static PetscErrorCode TSSetFromOptions_RK(TS ts, PetscOptionItems PetscOptionsObject)
1168d71ae5a4SJacob Faibussowitsch {
1169be5899b3SLisandro Dalcin TS_RK *rk = (TS_RK *)ts->data;
1170262ff7bbSBarry Smith
1171e4dd521cSBarry Smith PetscFunctionBegin;
1172d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "RK ODE solver options");
1173f68a32c8SEmil Constantinescu {
1174f68a32c8SEmil Constantinescu RKTableauLink link;
1175f68a32c8SEmil Constantinescu PetscInt count, choice;
11760fe4d17eSHong Zhang PetscBool flg, use_multirate = PETSC_FALSE;
1177f68a32c8SEmil Constantinescu const char **namelist;
11782c9cb062Sluzhanghpp
1179fbccb6d4SPierre Jolivet for (link = RKTableauList, count = 0; link; link = link->next, count++);
11809566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(count, (char ***)&namelist));
1181f68a32c8SEmil Constantinescu for (link = RKTableauList, count = 0; link; link = link->next, count++) namelist[count] = link->tab.name;
11829566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-ts_rk_multirate", "Use interpolation-based multirate RK method", "TSRKSetMultirate", rk->use_multirate, &use_multirate, &flg));
11831baa6e33SBarry Smith if (flg) PetscCall(TSRKSetMultirate(ts, use_multirate));
11849566063dSJacob Faibussowitsch PetscCall(PetscOptionsEList("-ts_rk_type", "Family of RK method", "TSRKSetType", (const char *const *)namelist, count, rk->tableau->name, &choice, &flg));
11859566063dSJacob Faibussowitsch if (flg) PetscCall(TSRKSetType(ts, namelist[choice]));
11869566063dSJacob Faibussowitsch PetscCall(PetscFree(namelist));
1187f68a32c8SEmil Constantinescu }
1188d0609cedSBarry Smith PetscOptionsHeadEnd();
1189d0609cedSBarry Smith PetscOptionsBegin(PetscObjectComm((PetscObject)ts), NULL, "Multirate methods options", "");
11909566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-ts_rk_dtratio", "time step ratio between slow and fast", "", rk->dtratio, &rk->dtratio, NULL));
1191d0609cedSBarry Smith PetscOptionsEnd();
11923ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1193e4dd521cSBarry Smith }
1194e4dd521cSBarry Smith
TSView_RK(TS ts,PetscViewer viewer)1195d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSView_RK(TS ts, PetscViewer viewer)
1196d71ae5a4SJacob Faibussowitsch {
11975f70b478SJed Brown TS_RK *rk = (TS_RK *)ts->data;
11989f196a02SMartin Diehl PetscBool isascii;
11992cdf8120Sasbjorn
1200e4dd521cSBarry Smith PetscFunctionBegin;
12019f196a02SMartin Diehl PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
12029f196a02SMartin Diehl if (isascii) {
12039c334d8fSLisandro Dalcin RKTableau tab = rk->tableau;
1204f68a32c8SEmil Constantinescu TSRKType rktype;
12050f7a28cdSStefano Zampini const PetscReal *c;
12060f7a28cdSStefano Zampini PetscInt s;
1207f68a32c8SEmil Constantinescu char buf[512];
12080f7a28cdSStefano Zampini PetscBool FSAL;
12090f7a28cdSStefano Zampini
12109566063dSJacob Faibussowitsch PetscCall(TSRKGetType(ts, &rktype));
12119566063dSJacob Faibussowitsch PetscCall(TSRKGetTableau(ts, &s, NULL, NULL, &c, NULL, NULL, NULL, &FSAL));
12129566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " RK type %s\n", rktype));
121363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Order: %" PetscInt_FMT "\n", tab->order));
12149566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " FSAL property: %s\n", FSAL ? "yes" : "no"));
12159566063dSJacob Faibussowitsch PetscCall(PetscFormatRealArray(buf, sizeof(buf), "% 8.6f", s, c));
12169566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Abscissa c = %s\n", buf));
12178370ee3bSLisandro Dalcin }
12183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1219f68a32c8SEmil Constantinescu }
1220f68a32c8SEmil Constantinescu
TSLoad_RK(TS ts,PetscViewer viewer)1221d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSLoad_RK(TS ts, PetscViewer viewer)
1222d71ae5a4SJacob Faibussowitsch {
12239c334d8fSLisandro Dalcin TSAdapt adapt;
1224f68a32c8SEmil Constantinescu
1225f68a32c8SEmil Constantinescu PetscFunctionBegin;
12269566063dSJacob Faibussowitsch PetscCall(TSGetAdapt(ts, &adapt));
12279566063dSJacob Faibussowitsch PetscCall(TSAdaptLoad(adapt, viewer));
12283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1229f68a32c8SEmil Constantinescu }
1230f68a32c8SEmil Constantinescu
12312ea87ba9SLisandro Dalcin /*@
1232bcf0153eSBarry Smith TSRKGetOrder - Get the order of the `TSRK` scheme
12332ea87ba9SLisandro Dalcin
123420f4b53cSBarry Smith Not Collective
12352ea87ba9SLisandro Dalcin
12362ea87ba9SLisandro Dalcin Input Parameter:
12372ea87ba9SLisandro Dalcin . ts - timestepping context
12382ea87ba9SLisandro Dalcin
12392ea87ba9SLisandro Dalcin Output Parameter:
1240bcf0153eSBarry Smith . order - order of `TSRK` scheme
12412ea87ba9SLisandro Dalcin
12422ea87ba9SLisandro Dalcin Level: intermediate
12432ea87ba9SLisandro Dalcin
12441cc06b55SBarry Smith .seealso: [](ch_ts), `TSRK`, `TSRKGetType()`
12452ea87ba9SLisandro Dalcin @*/
TSRKGetOrder(TS ts,PetscInt * order)1246d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRKGetOrder(TS ts, PetscInt *order)
1247d71ae5a4SJacob Faibussowitsch {
12482ea87ba9SLisandro Dalcin PetscFunctionBegin;
12492ea87ba9SLisandro Dalcin PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
12504f572ea9SToby Isaac PetscAssertPointer(order, 2);
1251cac4c232SBarry Smith PetscUseMethod(ts, "TSRKGetOrder_C", (TS, PetscInt *), (ts, order));
12523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
12532ea87ba9SLisandro Dalcin }
12542ea87ba9SLisandro Dalcin
1255cc4c1da9SBarry Smith /*@
1256bcf0153eSBarry Smith TSRKSetType - Set the type of the `TSRK` scheme
1257f68a32c8SEmil Constantinescu
125820f4b53cSBarry Smith Logically Collective
1259f68a32c8SEmil Constantinescu
1260d8d19677SJose E. Roman Input Parameters:
1261f68a32c8SEmil Constantinescu + ts - timestepping context
1262bcf0153eSBarry Smith - rktype - type of `TSRK` scheme
1263f68a32c8SEmil Constantinescu
1264bcf0153eSBarry Smith Options Database Key:
12659bd3e852SBarry Smith . -ts_rk_type - <1fe,2a,3,3bs,4,5f,5dp,5bs>
1266287c2655SBarry Smith
1267f68a32c8SEmil Constantinescu Level: intermediate
1268f68a32c8SEmil Constantinescu
12691cc06b55SBarry Smith .seealso: [](ch_ts), `TSRKGetType()`, `TSRK`, `TSRKType`, `TSRK1FE`, `TSRK2A`, `TSRK2B`, `TSRK3`, `TSRK3BS`, `TSRK4`, `TSRK5F`, `TSRK5DP`, `TSRK5BS`, `TSRK6VR`, `TSRK7VR`, `TSRK8VR`
1270f68a32c8SEmil Constantinescu @*/
TSRKSetType(TS ts,TSRKType rktype)1271d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRKSetType(TS ts, TSRKType rktype)
1272d71ae5a4SJacob Faibussowitsch {
1273f68a32c8SEmil Constantinescu PetscFunctionBegin;
1274f68a32c8SEmil Constantinescu PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
12754f572ea9SToby Isaac PetscAssertPointer(rktype, 2);
1276cac4c232SBarry Smith PetscTryMethod(ts, "TSRKSetType_C", (TS, TSRKType), (ts, rktype));
12773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1278f68a32c8SEmil Constantinescu }
1279f68a32c8SEmil Constantinescu
1280cc4c1da9SBarry Smith /*@
1281bcf0153eSBarry Smith TSRKGetType - Get the type of `TSRK` scheme
1282f68a32c8SEmil Constantinescu
128320f4b53cSBarry Smith Not Collective
1284f68a32c8SEmil Constantinescu
1285f68a32c8SEmil Constantinescu Input Parameter:
1286f68a32c8SEmil Constantinescu . ts - timestepping context
1287f68a32c8SEmil Constantinescu
1288f68a32c8SEmil Constantinescu Output Parameter:
1289bcf0153eSBarry Smith . rktype - type of `TSRK`-scheme
1290f68a32c8SEmil Constantinescu
1291f68a32c8SEmil Constantinescu Level: intermediate
1292f68a32c8SEmil Constantinescu
12931cc06b55SBarry Smith .seealso: [](ch_ts), `TSRKSetType()`
1294f68a32c8SEmil Constantinescu @*/
TSRKGetType(TS ts,TSRKType * rktype)1295d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRKGetType(TS ts, TSRKType *rktype)
1296d71ae5a4SJacob Faibussowitsch {
1297f68a32c8SEmil Constantinescu PetscFunctionBegin;
1298f68a32c8SEmil Constantinescu PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
1299cac4c232SBarry Smith PetscUseMethod(ts, "TSRKGetType_C", (TS, TSRKType *), (ts, rktype));
13003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1301f68a32c8SEmil Constantinescu }
1302f68a32c8SEmil Constantinescu
TSRKGetOrder_RK(TS ts,PetscInt * order)1303d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSRKGetOrder_RK(TS ts, PetscInt *order)
1304d71ae5a4SJacob Faibussowitsch {
13052ea87ba9SLisandro Dalcin TS_RK *rk = (TS_RK *)ts->data;
13062ea87ba9SLisandro Dalcin
13072ea87ba9SLisandro Dalcin PetscFunctionBegin;
13082ea87ba9SLisandro Dalcin *order = rk->tableau->order;
13093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
13102ea87ba9SLisandro Dalcin }
13112ea87ba9SLisandro Dalcin
TSRKGetType_RK(TS ts,TSRKType * rktype)1312d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSRKGetType_RK(TS ts, TSRKType *rktype)
1313d71ae5a4SJacob Faibussowitsch {
1314f68a32c8SEmil Constantinescu TS_RK *rk = (TS_RK *)ts->data;
1315f68a32c8SEmil Constantinescu
1316f68a32c8SEmil Constantinescu PetscFunctionBegin;
1317f68a32c8SEmil Constantinescu *rktype = rk->tableau->name;
13183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1319f68a32c8SEmil Constantinescu }
13202c9cb062Sluzhanghpp
TSRKSetType_RK(TS ts,TSRKType rktype)1321d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSRKSetType_RK(TS ts, TSRKType rktype)
1322d71ae5a4SJacob Faibussowitsch {
1323f68a32c8SEmil Constantinescu TS_RK *rk = (TS_RK *)ts->data;
1324f68a32c8SEmil Constantinescu PetscBool match;
1325f68a32c8SEmil Constantinescu RKTableauLink link;
1326f68a32c8SEmil Constantinescu
1327f68a32c8SEmil Constantinescu PetscFunctionBegin;
1328f68a32c8SEmil Constantinescu if (rk->tableau) {
13299566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(rk->tableau->name, rktype, &match));
13303ba16761SJacob Faibussowitsch if (match) PetscFunctionReturn(PETSC_SUCCESS);
1331f68a32c8SEmil Constantinescu }
1332f68a32c8SEmil Constantinescu for (link = RKTableauList; link; link = link->next) {
13339566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(link->tab.name, rktype, &match));
1334f68a32c8SEmil Constantinescu if (match) {
13359566063dSJacob Faibussowitsch if (ts->setupcalled) PetscCall(TSRKTableauReset(ts));
1336f68a32c8SEmil Constantinescu rk->tableau = &link->tab;
13379566063dSJacob Faibussowitsch if (ts->setupcalled) PetscCall(TSRKTableauSetUp(ts));
13382ffb9264SLisandro Dalcin ts->default_adapt_type = rk->tableau->bembed ? TSADAPTBASIC : TSADAPTNONE;
13393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1340f68a32c8SEmil Constantinescu }
1341f68a32c8SEmil Constantinescu }
134298921bdaSJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_UNKNOWN_TYPE, "Could not find '%s'", rktype);
1343e4dd521cSBarry Smith }
1344e4dd521cSBarry Smith
TSGetStages_RK(TS ts,PetscInt * ns,Vec ** Y)1345d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSGetStages_RK(TS ts, PetscInt *ns, Vec **Y)
1346d71ae5a4SJacob Faibussowitsch {
1347ff22ae23SHong Zhang TS_RK *rk = (TS_RK *)ts->data;
1348ff22ae23SHong Zhang
1349ff22ae23SHong Zhang PetscFunctionBegin;
13500429704eSStefano Zampini if (ns) *ns = rk->tableau->s;
1351d2daff3dSHong Zhang if (Y) *Y = rk->Y;
13523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1353ff22ae23SHong Zhang }
1354ff22ae23SHong Zhang
TSDestroy_RK(TS ts)1355d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSDestroy_RK(TS ts)
1356d71ae5a4SJacob Faibussowitsch {
1357b3a6b972SJed Brown PetscFunctionBegin;
13589566063dSJacob Faibussowitsch PetscCall(TSReset_RK(ts));
1359b3a6b972SJed Brown if (ts->dm) {
13609566063dSJacob Faibussowitsch PetscCall(DMCoarsenHookRemove(ts->dm, DMCoarsenHook_TSRK, DMRestrictHook_TSRK, ts));
13619566063dSJacob Faibussowitsch PetscCall(DMSubDomainHookRemove(ts->dm, DMSubDomainHook_TSRK, DMSubDomainRestrictHook_TSRK, ts));
1362b3a6b972SJed Brown }
13639566063dSJacob Faibussowitsch PetscCall(PetscFree(ts->data));
13649566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSRKGetOrder_C", NULL));
13659566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSRKGetType_C", NULL));
13669566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSRKSetType_C", NULL));
13679566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSRKGetTableau_C", NULL));
13689566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSRKSetMultirate_C", NULL));
13699566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSRKGetMultirate_C", NULL));
13702e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSSetUp_RK_MultirateSplit_C", NULL));
13712e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSReset_RK_MultirateSplit_C", NULL));
13722e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSSetUp_RK_MultirateNonsplit_C", NULL));
13732e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSReset_RK_MultirateNonsplit_C", NULL));
13743ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1375b3a6b972SJed Brown }
1376ff22ae23SHong Zhang
13773ca0882eSHong Zhang /*
13783ca0882eSHong Zhang This defines the nonlinear equation that is to be solved with SNES
13793ca0882eSHong Zhang We do not need to solve the equation; we just use SNES to approximate the Jacobian
13803ca0882eSHong Zhang */
SNESTSFormFunction_RK(SNES snes,Vec x,Vec y,TS ts)1381d71ae5a4SJacob Faibussowitsch static PetscErrorCode SNESTSFormFunction_RK(SNES snes, Vec x, Vec y, TS ts)
1382d71ae5a4SJacob Faibussowitsch {
13833ca0882eSHong Zhang TS_RK *rk = (TS_RK *)ts->data;
13843ca0882eSHong Zhang DM dm, dmsave;
13853ca0882eSHong Zhang
13863ca0882eSHong Zhang PetscFunctionBegin;
13879566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm));
13883ca0882eSHong Zhang /* DM monkey-business allows user code to call TSGetDM() inside of functions evaluated on levels of FAS */
13893ca0882eSHong Zhang dmsave = ts->dm;
13903ca0882eSHong Zhang ts->dm = dm;
13919566063dSJacob Faibussowitsch PetscCall(TSComputeRHSFunction(ts, rk->stage_time, x, y));
13923ca0882eSHong Zhang ts->dm = dmsave;
13933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
13943ca0882eSHong Zhang }
13953ca0882eSHong Zhang
SNESTSFormJacobian_RK(SNES snes,Vec x,Mat A,Mat B,TS ts)1396d71ae5a4SJacob Faibussowitsch static PetscErrorCode SNESTSFormJacobian_RK(SNES snes, Vec x, Mat A, Mat B, TS ts)
1397d71ae5a4SJacob Faibussowitsch {
13983ca0882eSHong Zhang TS_RK *rk = (TS_RK *)ts->data;
13993ca0882eSHong Zhang DM dm, dmsave;
14003ca0882eSHong Zhang
14013ca0882eSHong Zhang PetscFunctionBegin;
14029566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm));
14033ca0882eSHong Zhang dmsave = ts->dm;
14043ca0882eSHong Zhang ts->dm = dm;
14059566063dSJacob Faibussowitsch PetscCall(TSComputeRHSJacobian(ts, rk->stage_time, x, A, B));
14063ca0882eSHong Zhang ts->dm = dmsave;
14073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
14083ca0882eSHong Zhang }
14093ca0882eSHong Zhang
1410cc4c1da9SBarry Smith /*@
1411bcf0153eSBarry Smith TSRKSetMultirate - Use the interpolation-based multirate `TSRK` method
141221052c0cSHong Zhang
141320f4b53cSBarry Smith Logically Collective
141421052c0cSHong Zhang
1415d8d19677SJose E. Roman Input Parameters:
141621052c0cSHong Zhang + ts - timestepping context
1417bcf0153eSBarry 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
141821052c0cSHong Zhang
1419bcf0153eSBarry Smith Options Database Key:
142021052c0cSHong Zhang . -ts_rk_multirate - <true,false>
142121052c0cSHong Zhang
142221052c0cSHong Zhang Level: intermediate
142321052c0cSHong Zhang
1424bcf0153eSBarry Smith Note:
1425da81f932SPierre 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).
1426bcf0153eSBarry Smith
14271cc06b55SBarry Smith .seealso: [](ch_ts), `TSRK`, `TSRKGetMultirate()`
142821052c0cSHong Zhang @*/
TSRKSetMultirate(TS ts,PetscBool use_multirate)1429d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRKSetMultirate(TS ts, PetscBool use_multirate)
1430d71ae5a4SJacob Faibussowitsch {
14318a4be4dbSHong Zhang PetscFunctionBegin;
1432cac4c232SBarry Smith PetscTryMethod(ts, "TSRKSetMultirate_C", (TS, PetscBool), (ts, use_multirate));
14333ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
143421052c0cSHong Zhang }
143521052c0cSHong Zhang
1436cc4c1da9SBarry Smith /*@
1437bcf0153eSBarry Smith TSRKGetMultirate - Gets whether to use the interpolation-based multirate `TSRK` method
143821052c0cSHong Zhang
143920f4b53cSBarry Smith Not Collective
144021052c0cSHong Zhang
144121052c0cSHong Zhang Input Parameter:
144221052c0cSHong Zhang . ts - timestepping context
144321052c0cSHong Zhang
144421052c0cSHong Zhang Output Parameter:
1445bcf0153eSBarry Smith . use_multirate - `PETSC_TRUE` if the multirate RK method is enabled, `PETSC_FALSE` otherwise
144621052c0cSHong Zhang
144721052c0cSHong Zhang Level: intermediate
144821052c0cSHong Zhang
14491cc06b55SBarry Smith .seealso: [](ch_ts), `TSRK`, `TSRKSetMultirate()`
145021052c0cSHong Zhang @*/
TSRKGetMultirate(TS ts,PetscBool * use_multirate)1451d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRKGetMultirate(TS ts, PetscBool *use_multirate)
1452d71ae5a4SJacob Faibussowitsch {
14537dbacdf2SHong Zhang PetscFunctionBegin;
1454cac4c232SBarry Smith PetscUseMethod(ts, "TSRKGetMultirate_C", (TS, PetscBool *), (ts, use_multirate));
14553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
145621052c0cSHong Zhang }
145721052c0cSHong Zhang
1458ebe3b25bSBarry Smith /*MC
1459f68a32c8SEmil Constantinescu TSRK - ODE and DAE solver using Runge-Kutta schemes
1460ebe3b25bSBarry Smith
1461dd8e379bSPierre Jolivet The user should provide the right-hand side of the equation
1462bcf0153eSBarry Smith using `TSSetRHSFunction()`.
1463ebe3b25bSBarry Smith
1464d41222bbSBarry Smith Level: beginner
1465d41222bbSBarry Smith
1466bcf0153eSBarry Smith Notes:
1467bcf0153eSBarry Smith The default is `TSRK3BS`, it can be changed with `TSRKSetType()` or -ts_rk_type
1468ebe3b25bSBarry Smith
14691cc06b55SBarry Smith .seealso: [](ch_ts), `TSCreate()`, `TS`, `TSRK`, `TSSetType()`, `TSRKSetType()`, `TSRKGetType()`, `TSRK2D`, `TSRK2E`, `TSRK3`,
1470bcf0153eSBarry Smith `TSRK4`, `TSRK5`, `TSRKPRSSP2`, `TSRKBPR3`, `TSRKType`, `TSRKRegister()`, `TSRKSetMultirate()`, `TSRKGetMultirate()`, `TSType`
1471ebe3b25bSBarry Smith M*/
TSCreate_RK(TS ts)1472d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode TSCreate_RK(TS ts)
1473d71ae5a4SJacob Faibussowitsch {
14741566a47fSLisandro Dalcin TS_RK *rk;
1475e4dd521cSBarry Smith
1476e4dd521cSBarry Smith PetscFunctionBegin;
14779566063dSJacob Faibussowitsch PetscCall(TSRKInitializePackage());
1478f68a32c8SEmil Constantinescu
1479f68a32c8SEmil Constantinescu ts->ops->reset = TSReset_RK;
14805f70b478SJed Brown ts->ops->destroy = TSDestroy_RK;
14815f70b478SJed Brown ts->ops->view = TSView_RK;
1482f68a32c8SEmil Constantinescu ts->ops->load = TSLoad_RK;
1483f68a32c8SEmil Constantinescu ts->ops->setup = TSSetUp_RK;
1484f68a32c8SEmil Constantinescu ts->ops->interpolate = TSInterpolate_RK;
14852c9cb062Sluzhanghpp ts->ops->step = TSStep_RK;
1486f68a32c8SEmil Constantinescu ts->ops->evaluatestep = TSEvaluateStep_RK;
1487fecfb714SLisandro Dalcin ts->ops->rollback = TSRollBack_RK;
1488f68a32c8SEmil Constantinescu ts->ops->setfromoptions = TSSetFromOptions_RK;
1489ff22ae23SHong Zhang ts->ops->getstages = TSGetStages_RK;
1490e4dd521cSBarry Smith
14913ca0882eSHong Zhang ts->ops->snesfunction = SNESTSFormFunction_RK;
14923ca0882eSHong Zhang ts->ops->snesjacobian = SNESTSFormJacobian_RK;
14930f7a1166SHong Zhang ts->ops->adjointintegral = TSAdjointCostIntegral_RK;
149413af1a74SHong Zhang ts->ops->adjointsetup = TSAdjointSetUp_RK;
149513af1a74SHong Zhang ts->ops->adjointstep = TSAdjointStep_RK;
149613af1a74SHong Zhang ts->ops->adjointreset = TSAdjointReset_RK;
14970f7a1166SHong Zhang
149813af1a74SHong Zhang ts->ops->forwardintegral = TSForwardCostIntegral_RK;
1499922a638cSHong Zhang ts->ops->forwardsetup = TSForwardSetUp_RK;
1500922a638cSHong Zhang ts->ops->forwardreset = TSForwardReset_RK;
1501922a638cSHong Zhang ts->ops->forwardstep = TSForwardStep_RK;
1502922a638cSHong Zhang ts->ops->forwardgetstages = TSForwardGetStages_RK;
1503922a638cSHong Zhang
15044dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&rk));
15051566a47fSLisandro Dalcin ts->data = (void *)rk;
1506e4dd521cSBarry Smith
15079566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSRKGetOrder_C", TSRKGetOrder_RK));
15089566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSRKGetType_C", TSRKGetType_RK));
15099566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSRKSetType_C", TSRKSetType_RK));
15109566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSRKGetTableau_C", TSRKGetTableau_RK));
15119566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSRKSetMultirate_C", TSRKSetMultirate_RK));
15129566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSRKGetMultirate_C", TSRKGetMultirate_RK));
1513be5899b3SLisandro Dalcin
15149566063dSJacob Faibussowitsch PetscCall(TSRKSetType(ts, TSRKDefault));
151590b67129SHong Zhang rk->dtratio = 1;
15163ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1517e4dd521cSBarry Smith }
1518