xref: /petsc/src/ts/impls/rosw/rosw.c (revision 48665b53e116210831f933551bb75372679e40a5)
1e27a552bSJed Brown /*
261692a83SJed Brown   Code for timestepping with Rosenbrock W methods
3e27a552bSJed Brown 
4e27a552bSJed Brown   Notes:
5e27a552bSJed Brown   The general system is written as
6e27a552bSJed Brown 
7f9c1d6abSBarry Smith   F(t,U,Udot) = G(t,U)
8e27a552bSJed Brown 
9f9c1d6abSBarry Smith   where F represents the stiff part of the physics and G represents the non-stiff part.
10f9c1d6abSBarry Smith   This method is designed to be linearly implicit on F and can use an approximate and lagged Jacobian.
11e27a552bSJed Brown 
12e27a552bSJed Brown */
13af0996ceSBarry Smith #include <petsc/private/tsimpl.h> /*I   "petscts.h"   I*/
141e25c274SJed Brown #include <petscdm.h>
15e27a552bSJed Brown 
16af0996ceSBarry Smith #include <petsc/private/kernels/blockinvert.h>
1761692a83SJed Brown 
1819fd82e9SBarry Smith static TSRosWType TSRosWDefault = TSROSWRA34PW2;
19e27a552bSJed Brown static PetscBool  TSRosWRegisterAllCalled;
20e27a552bSJed Brown static PetscBool  TSRosWPackageInitialized;
21e27a552bSJed Brown 
2261692a83SJed Brown typedef struct _RosWTableau *RosWTableau;
2361692a83SJed Brown struct _RosWTableau {
24e27a552bSJed Brown   char      *name;
25e27a552bSJed Brown   PetscInt   order;             /* Classical approximation order of the method */
26e27a552bSJed Brown   PetscInt   s;                 /* Number of stages */
27f4aed992SEmil Constantinescu   PetscInt   pinterp;           /* Interpolation order */
2861692a83SJed Brown   PetscReal *A;                 /* Propagation table, strictly lower triangular */
2961692a83SJed Brown   PetscReal *Gamma;             /* Stage table, lower triangular with nonzero diagonal */
30c17803e7SJed Brown   PetscBool *GammaZeroDiag;     /* Diagonal entries that are zero in stage table Gamma, vector indicating explicit statages */
3143b21953SEmil Constantinescu   PetscReal *GammaExplicitCorr; /* Coefficients for correction terms needed for explicit stages in transformed variables*/
3261692a83SJed Brown   PetscReal *b;                 /* Step completion table */
33fe7e6d57SJed Brown   PetscReal *bembed;            /* Step completion table for embedded method of order one less */
3461692a83SJed Brown   PetscReal *ASum;              /* Row sum of A */
3561692a83SJed Brown   PetscReal *GammaSum;          /* Row sum of Gamma, only needed for non-autonomous systems */
3661692a83SJed Brown   PetscReal *At;                /* Propagation table in transformed variables */
3761692a83SJed Brown   PetscReal *bt;                /* Step completion table in transformed variables */
38fe7e6d57SJed Brown   PetscReal *bembedt;           /* Step completion table of order one less in transformed variables */
3961692a83SJed Brown   PetscReal *GammaInv;          /* Inverse of Gamma, used for transformed variables */
408d59e960SJed Brown   PetscReal  ccfl;              /* Placeholder for CFL coefficient relative to forward Euler */
413ca35412SEmil Constantinescu   PetscReal *binterpt;          /* Dense output formula */
42e27a552bSJed Brown };
4361692a83SJed Brown typedef struct _RosWTableauLink *RosWTableauLink;
4461692a83SJed Brown struct _RosWTableauLink {
4561692a83SJed Brown   struct _RosWTableau tab;
4661692a83SJed Brown   RosWTableauLink     next;
47e27a552bSJed Brown };
4861692a83SJed Brown static RosWTableauLink RosWTableauList;
49e27a552bSJed Brown 
50e27a552bSJed Brown typedef struct {
5161692a83SJed Brown   RosWTableau  tableau;
5261692a83SJed Brown   Vec         *Y;            /* States computed during the step, used to complete the step */
53e27a552bSJed Brown   Vec          Ydot;         /* Work vector holding Ydot during residual evaluation */
5461692a83SJed Brown   Vec          Ystage;       /* Work vector for the state value at each stage */
5561692a83SJed Brown   Vec          Zdot;         /* Ydot = Zdot + shift*Y */
5661692a83SJed Brown   Vec          Zstage;       /* Y = Zstage + Y */
57be5899b3SLisandro Dalcin   Vec          vec_sol_prev; /* Solution from the previous step (used for interpolation and rollback)*/
581c3436cfSJed Brown   PetscScalar *work;         /* Scalar work space of length number of stages, used to prepare VecMAXPY() */
59b296d7d5SJed Brown   PetscReal    scoeff;       /* shift = scoeff/dt */
60e27a552bSJed Brown   PetscReal    stage_time;
61c17803e7SJed Brown   PetscReal    stage_explicit;     /* Flag indicates that the current stage is explicit */
6261692a83SJed Brown   PetscBool    recompute_jacobian; /* Recompute the Jacobian at each stage, default is to freeze the Jacobian at the start of each step */
63108c343cSJed Brown   TSStepStatus status;
64e27a552bSJed Brown } TS_RosW;
65e27a552bSJed Brown 
66fe7e6d57SJed Brown /*MC
673606a31eSEmil Constantinescu      TSROSWTHETA1 - One stage first order L-stable Rosenbrock-W scheme (aka theta method).
683606a31eSEmil Constantinescu 
693606a31eSEmil Constantinescu      Only an approximate Jacobian is needed.
703606a31eSEmil Constantinescu 
713606a31eSEmil Constantinescu      Level: intermediate
723606a31eSEmil Constantinescu 
731cc06b55SBarry Smith .seealso: [](ch_ts), `TSROSW`
743606a31eSEmil Constantinescu M*/
753606a31eSEmil Constantinescu 
763606a31eSEmil Constantinescu /*MC
773606a31eSEmil Constantinescu      TSROSWTHETA2 - One stage second order A-stable Rosenbrock-W scheme (aka theta method).
783606a31eSEmil Constantinescu 
793606a31eSEmil Constantinescu      Only an approximate Jacobian is needed.
803606a31eSEmil Constantinescu 
813606a31eSEmil Constantinescu      Level: intermediate
823606a31eSEmil Constantinescu 
831cc06b55SBarry Smith .seealso: [](ch_ts), `TSROSW`
843606a31eSEmil Constantinescu M*/
853606a31eSEmil Constantinescu 
863606a31eSEmil Constantinescu /*MC
87fe7e6d57SJed Brown      TSROSW2M - Two stage second order L-stable Rosenbrock-W scheme.
88fe7e6d57SJed Brown 
89fe7e6d57SJed Brown      Only an approximate Jacobian is needed. By default, it is only recomputed once per step. This method is a reflection of TSROSW2P.
90fe7e6d57SJed Brown 
91fe7e6d57SJed Brown      Level: intermediate
92fe7e6d57SJed Brown 
931cc06b55SBarry Smith .seealso: [](ch_ts), `TSROSW`
94fe7e6d57SJed Brown M*/
95fe7e6d57SJed Brown 
96fe7e6d57SJed Brown /*MC
97fe7e6d57SJed Brown      TSROSW2P - Two stage second order L-stable Rosenbrock-W scheme.
98fe7e6d57SJed Brown 
99fe7e6d57SJed Brown      Only an approximate Jacobian is needed. By default, it is only recomputed once per step. This method is a reflection of TSROSW2M.
100fe7e6d57SJed Brown 
101fe7e6d57SJed Brown      Level: intermediate
102fe7e6d57SJed Brown 
1031cc06b55SBarry Smith .seealso: [](ch_ts), `TSROSW`
104fe7e6d57SJed Brown M*/
105fe7e6d57SJed Brown 
106fe7e6d57SJed Brown /*MC
1071d27aa22SBarry Smith      TSROSWRA3PW - Three stage third order Rosenbrock-W scheme for PDAE of index 1 {cite}`rang_2005`
108fe7e6d57SJed Brown 
109fe7e6d57SJed Brown      Only an approximate Jacobian is needed. By default, it is only recomputed once per step.
110fe7e6d57SJed Brown 
111fe7e6d57SJed Brown      This is strongly A-stable with R(infty) = 0.73. The embedded method of order 2 is strongly A-stable with R(infty) = 0.73.
112fe7e6d57SJed Brown 
113bcf0153eSBarry Smith      Level: intermediate
114bcf0153eSBarry Smith 
1151cc06b55SBarry Smith .seealso: [](ch_ts), `TSROSW`
116fe7e6d57SJed Brown M*/
117fe7e6d57SJed Brown 
118fe7e6d57SJed Brown /*MC
1191d27aa22SBarry Smith      TSROSWRA34PW2 - Four stage third order L-stable Rosenbrock-W scheme for PDAE of index 1 {cite}`rang_2005`.
120fe7e6d57SJed Brown 
121fe7e6d57SJed Brown      Only an approximate Jacobian is needed. By default, it is only recomputed once per step.
122fe7e6d57SJed Brown 
123fe7e6d57SJed Brown      This is strongly A-stable with R(infty) = 0. The embedded method of order 2 is strongly A-stable with R(infty) = 0.48.
124fe7e6d57SJed Brown 
125bcf0153eSBarry Smith      Level: intermediate
126bcf0153eSBarry Smith 
1271cc06b55SBarry Smith .seealso: [](ch_ts), `TSROSW`
128fe7e6d57SJed Brown M*/
129fe7e6d57SJed Brown 
130ef3c5b88SJed Brown /*MC
1311d27aa22SBarry Smith      TSROSWRODAS3 - Four stage third order L-stable Rosenbrock scheme {cite}`sandu_1997`
132ef3c5b88SJed Brown 
133ef3c5b88SJed Brown      By default, the Jacobian is only recomputed once per step.
134ef3c5b88SJed Brown 
135ef3c5b88SJed Brown      Both the third order and embedded second order methods are stiffly accurate and L-stable.
136ef3c5b88SJed Brown 
137bcf0153eSBarry Smith      Level: intermediate
138bcf0153eSBarry Smith 
1391cc06b55SBarry Smith .seealso: [](ch_ts), `TSROSW`, `TSROSWSANDU3`
140ef3c5b88SJed Brown M*/
141ef3c5b88SJed Brown 
142ef3c5b88SJed Brown /*MC
143*48665b53SJed Brown      TSROSWRODASPR - Six stage fourth order L-stable Rosenbrock scheme {cite}`rang2015improved`
144*48665b53SJed Brown 
145*48665b53SJed Brown      By default, the Jacobian is only recomputed once per step.
146*48665b53SJed Brown 
147*48665b53SJed Brown      Both the fourth order and embedded third order methods are stiffly accurate and L-stable.
148*48665b53SJed Brown      The method is B_{PR} consistent of order 3, which ensures convergence order for non-stiff, medium stiff, and stiff problems.
149*48665b53SJed Brown 
150*48665b53SJed Brown      Level: intermediate
151*48665b53SJed Brown 
152*48665b53SJed Brown .seealso: [](ch_ts), `TSROSW`, `TSROSWSANDU3`
153*48665b53SJed Brown M*/
154*48665b53SJed Brown 
155*48665b53SJed Brown /*MC
1561d27aa22SBarry Smith      TSROSWSANDU3 - Three stage third order L-stable Rosenbrock scheme {cite}`sandu_1997`
157ef3c5b88SJed Brown 
158ef3c5b88SJed Brown      By default, the Jacobian is only recomputed once per step.
159ef3c5b88SJed Brown 
160ef3c5b88SJed Brown      The third order method is L-stable, but not stiffly accurate.
161ef3c5b88SJed Brown      The second order embedded method is strongly A-stable with R(infty) = 0.5.
162ef3c5b88SJed Brown      The internal stages are L-stable.
1631d27aa22SBarry Smith      This method is called ROS3 in {cite}`sandu_1997`.
164ef3c5b88SJed Brown 
165bcf0153eSBarry Smith      Level: intermediate
166bcf0153eSBarry Smith 
1671cc06b55SBarry Smith .seealso: [](ch_ts), `TSROSW`, `TSROSWRODAS3`
168ef3c5b88SJed Brown M*/
169ef3c5b88SJed Brown 
170961f28d0SJed Brown /*MC
171961f28d0SJed Brown      TSROSWASSP3P3S1C - A-stable Rosenbrock-W method with SSP explicit part, third order, three stages
172961f28d0SJed Brown 
173961f28d0SJed Brown      By default, the Jacobian is only recomputed once per step.
174961f28d0SJed Brown 
175961f28d0SJed Brown      A-stable SPP explicit order 3, 3 stages, CFL 1 (eff = 1/3)
176961f28d0SJed Brown 
177bcf0153eSBarry Smith      Level: intermediate
178bcf0153eSBarry Smith 
1791cc06b55SBarry Smith .seealso: [](ch_ts), `TSROSW`, `TSROSWLASSP3P4S2C`, `TSROSWLLSSP3P4S2C`, `SSP`
180961f28d0SJed Brown M*/
181961f28d0SJed Brown 
182961f28d0SJed Brown /*MC
183998eb97aSJed Brown      TSROSWLASSP3P4S2C - L-stable Rosenbrock-W method with SSP explicit part, third order, four stages
184961f28d0SJed Brown 
185961f28d0SJed Brown      By default, the Jacobian is only recomputed once per step.
186961f28d0SJed Brown 
187961f28d0SJed Brown      L-stable (A-stable embedded) SPP explicit order 3, 4 stages, CFL 2 (eff = 1/2)
188961f28d0SJed Brown 
189bcf0153eSBarry Smith      Level: intermediate
190bcf0153eSBarry Smith 
1911cc06b55SBarry Smith .seealso: [](ch_ts), `TSROSW`, `TSROSWASSP3P3S1C`, `TSROSWLLSSP3P4S2C`, `TSSSP`
192961f28d0SJed Brown M*/
193961f28d0SJed Brown 
194961f28d0SJed Brown /*MC
195998eb97aSJed Brown      TSROSWLLSSP3P4S2C - L-stable Rosenbrock-W method with SSP explicit part, third order, four stages
196961f28d0SJed Brown 
197961f28d0SJed Brown      By default, the Jacobian is only recomputed once per step.
198961f28d0SJed Brown 
199961f28d0SJed Brown      L-stable (L-stable embedded) SPP explicit order 3, 4 stages, CFL 2 (eff = 1/2)
200961f28d0SJed Brown 
201bcf0153eSBarry Smith      Level: intermediate
202bcf0153eSBarry Smith 
2031cc06b55SBarry Smith .seealso: [](ch_ts), `TSROSW`, `TSROSWASSP3P3S1C`, `TSROSWLASSP3P4S2C`, `TSSSP`
204961f28d0SJed Brown M*/
205961f28d0SJed Brown 
20642faf41dSJed Brown /*MC
2071d27aa22SBarry Smith      TSROSWGRK4T - four stage, fourth order Rosenbrock (not W) method from Kaps and Rentrop {cite}`kaps1979generalized`
20842faf41dSJed Brown 
20942faf41dSJed Brown      By default, the Jacobian is only recomputed once per step.
21042faf41dSJed Brown 
21142faf41dSJed Brown      A(89.3 degrees)-stable, |R(infty)| = 0.454.
21242faf41dSJed Brown 
21342faf41dSJed Brown      This method does not provide a dense output formula.
21442faf41dSJed Brown 
215bcf0153eSBarry Smith      Level: intermediate
216bcf0153eSBarry Smith 
2171d27aa22SBarry Smith      Note:
2181d27aa22SBarry Smith      See Section 4 Table 7.2 in {cite}`wanner1996solving`
21942faf41dSJed Brown 
2201cc06b55SBarry Smith .seealso: [](ch_ts), `TSROSW`, `TSROSWSHAMP4`, `TSROSWVELDD4`, `TSROSW4L`
22142faf41dSJed Brown M*/
22242faf41dSJed Brown 
22342faf41dSJed Brown /*MC
2241d27aa22SBarry Smith      TSROSWSHAMP4 - four stage, fourth order Rosenbrock (not W) method from Shampine {cite}`shampine1982implementation`
22542faf41dSJed Brown 
22642faf41dSJed Brown      By default, the Jacobian is only recomputed once per step.
22742faf41dSJed Brown 
22842faf41dSJed Brown      A-stable, |R(infty)| = 1/3.
22942faf41dSJed Brown 
23042faf41dSJed Brown      This method does not provide a dense output formula.
23142faf41dSJed Brown 
232bcf0153eSBarry Smith      Level: intermediate
233bcf0153eSBarry Smith 
2341d27aa22SBarry Smith      Note:
23515229ffcSPierre Jolivet      See Section 4 Table 7.2 in {cite}`wanner1996solving`
23642faf41dSJed Brown 
2371cc06b55SBarry Smith .seealso: [](ch_ts), `TSROSW`, `TSROSWGRK4T`, `TSROSWVELDD4`, `TSROSW4L`
23842faf41dSJed Brown M*/
23942faf41dSJed Brown 
24042faf41dSJed Brown /*MC
2411d27aa22SBarry Smith      TSROSWVELDD4 - four stage, fourth order Rosenbrock (not W) method from van Veldhuizen {cite}`veldhuizen1984d`
24242faf41dSJed Brown 
24342faf41dSJed Brown      By default, the Jacobian is only recomputed once per step.
24442faf41dSJed Brown 
24542faf41dSJed Brown      A(89.5 degrees)-stable, |R(infty)| = 0.24.
24642faf41dSJed Brown 
24742faf41dSJed Brown      This method does not provide a dense output formula.
24842faf41dSJed Brown 
249bcf0153eSBarry Smith      Level: intermediate
250bcf0153eSBarry Smith 
2511d27aa22SBarry Smith      Note:
2521d27aa22SBarry Smith      See Section 4 Table 7.2 in {cite}`wanner1996solving`
25342faf41dSJed Brown 
2541cc06b55SBarry Smith .seealso: [](ch_ts), `TSROSW`, `TSROSWGRK4T`, `TSROSWSHAMP4`, `TSROSW4L`
25542faf41dSJed Brown M*/
25642faf41dSJed Brown 
25742faf41dSJed Brown /*MC
25842faf41dSJed Brown      TSROSW4L - four stage, fourth order Rosenbrock (not W) method
25942faf41dSJed Brown 
26042faf41dSJed Brown      By default, the Jacobian is only recomputed once per step.
26142faf41dSJed Brown 
26242faf41dSJed Brown      A-stable and L-stable
26342faf41dSJed Brown 
26442faf41dSJed Brown      This method does not provide a dense output formula.
26542faf41dSJed Brown 
266bcf0153eSBarry Smith      Level: intermediate
267bcf0153eSBarry Smith 
2681d27aa22SBarry Smith      Note:
26915229ffcSPierre Jolivet      See Section 4 Table 7.2 in {cite}`wanner1996solving`
27042faf41dSJed Brown 
2711cc06b55SBarry Smith .seealso: [](ch_ts), `TSROSW`, `TSROSWGRK4T`, `TSROSWSHAMP4`, `TSROSW4L`
27242faf41dSJed Brown M*/
27342faf41dSJed Brown 
274e27a552bSJed Brown /*@C
275bcf0153eSBarry Smith   TSRosWRegisterAll - Registers all of the Rosenbrock-W methods in `TSROSW`
276e27a552bSJed Brown 
2771d27aa22SBarry Smith   Not Collective, but should be called by all MPI processes which will need the schemes to be registered
278e27a552bSJed Brown 
279e27a552bSJed Brown   Level: advanced
280e27a552bSJed Brown 
2811cc06b55SBarry Smith .seealso: [](ch_ts), `TSROSW`, `TSRosWRegisterDestroy()`
282e27a552bSJed Brown @*/
283d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRosWRegisterAll(void)
284d71ae5a4SJacob Faibussowitsch {
285e27a552bSJed Brown   PetscFunctionBegin;
2863ba16761SJacob Faibussowitsch   if (TSRosWRegisterAllCalled) PetscFunctionReturn(PETSC_SUCCESS);
287e27a552bSJed Brown   TSRosWRegisterAllCalled = PETSC_TRUE;
288e27a552bSJed Brown 
289e27a552bSJed Brown   {
290bbd56ea5SKarl Rupp     const PetscReal A        = 0;
291bbd56ea5SKarl Rupp     const PetscReal Gamma    = 1;
292bbd56ea5SKarl Rupp     const PetscReal b        = 1;
293bbd56ea5SKarl Rupp     const PetscReal binterpt = 1;
2941f80e275SEmil Constantinescu 
2959566063dSJacob Faibussowitsch     PetscCall(TSRosWRegister(TSROSWTHETA1, 1, 1, &A, &Gamma, &b, NULL, 1, &binterpt));
2963606a31eSEmil Constantinescu   }
2973606a31eSEmil Constantinescu 
2983606a31eSEmil Constantinescu   {
299bbd56ea5SKarl Rupp     const PetscReal A        = 0;
300bbd56ea5SKarl Rupp     const PetscReal Gamma    = 0.5;
301bbd56ea5SKarl Rupp     const PetscReal b        = 1;
302bbd56ea5SKarl Rupp     const PetscReal binterpt = 1;
303bbd56ea5SKarl Rupp 
3049566063dSJacob Faibussowitsch     PetscCall(TSRosWRegister(TSROSWTHETA2, 2, 1, &A, &Gamma, &b, NULL, 1, &binterpt));
3053606a31eSEmil Constantinescu   }
3063606a31eSEmil Constantinescu 
3073606a31eSEmil Constantinescu   {
308da80777bSKarl Rupp     /*const PetscReal g = 1. + 1./PetscSqrtReal(2.0);   Direct evaluation: 1.707106781186547524401. Used for setting up arrays of values known at compile time below. */
309b16ce868SStefano Zampini     const PetscReal A[2][2] = {
3109371c9d4SSatish Balay       {0,  0},
3119371c9d4SSatish Balay       {1., 0}
312b16ce868SStefano Zampini     };
313b16ce868SStefano Zampini     const PetscReal Gamma[2][2] = {
314b16ce868SStefano Zampini       {1.707106781186547524401,       0                      },
315b16ce868SStefano Zampini       {-2. * 1.707106781186547524401, 1.707106781186547524401}
316b16ce868SStefano Zampini     };
317b16ce868SStefano Zampini     const PetscReal b[2]  = {0.5, 0.5};
318b16ce868SStefano Zampini     const PetscReal b1[2] = {1.0, 0.0};
3191f80e275SEmil Constantinescu     PetscReal       binterpt[2][2];
320da80777bSKarl Rupp     binterpt[0][0] = 1.707106781186547524401 - 1.0;
321da80777bSKarl Rupp     binterpt[1][0] = 2.0 - 1.707106781186547524401;
322da80777bSKarl Rupp     binterpt[0][1] = 1.707106781186547524401 - 1.5;
323da80777bSKarl Rupp     binterpt[1][1] = 1.5 - 1.707106781186547524401;
324bbd56ea5SKarl Rupp 
3259566063dSJacob Faibussowitsch     PetscCall(TSRosWRegister(TSROSW2P, 2, 2, &A[0][0], &Gamma[0][0], b, b1, 2, &binterpt[0][0]));
326e27a552bSJed Brown   }
327e27a552bSJed Brown   {
328da80777bSKarl Rupp     /*const PetscReal g = 1. - 1./PetscSqrtReal(2.0);   Direct evaluation: 0.2928932188134524755992. Used for setting up arrays of values known at compile time below. */
329b16ce868SStefano Zampini     const PetscReal A[2][2] = {
3309371c9d4SSatish Balay       {0,  0},
3319371c9d4SSatish Balay       {1., 0}
332b16ce868SStefano Zampini     };
333b16ce868SStefano Zampini     const PetscReal Gamma[2][2] = {
334b16ce868SStefano Zampini       {0.2928932188134524755992,       0                       },
335b16ce868SStefano Zampini       {-2. * 0.2928932188134524755992, 0.2928932188134524755992}
336b16ce868SStefano Zampini     };
337b16ce868SStefano Zampini     const PetscReal b[2]  = {0.5, 0.5};
338b16ce868SStefano Zampini     const PetscReal b1[2] = {1.0, 0.0};
3391f80e275SEmil Constantinescu     PetscReal       binterpt[2][2];
340da80777bSKarl Rupp     binterpt[0][0] = 0.2928932188134524755992 - 1.0;
341da80777bSKarl Rupp     binterpt[1][0] = 2.0 - 0.2928932188134524755992;
342da80777bSKarl Rupp     binterpt[0][1] = 0.2928932188134524755992 - 1.5;
343da80777bSKarl Rupp     binterpt[1][1] = 1.5 - 0.2928932188134524755992;
344bbd56ea5SKarl Rupp 
3459566063dSJacob Faibussowitsch     PetscCall(TSRosWRegister(TSROSW2M, 2, 2, &A[0][0], &Gamma[0][0], b, b1, 2, &binterpt[0][0]));
346fe7e6d57SJed Brown   }
347fe7e6d57SJed Brown   {
348da80777bSKarl Rupp     /*const PetscReal g = 7.8867513459481287e-01; Directly written in-place below */
3491f80e275SEmil Constantinescu     PetscReal       binterpt[3][2];
350b16ce868SStefano Zampini     const PetscReal A[3][3] = {
3519371c9d4SSatish Balay       {0,                      0, 0},
352fe7e6d57SJed Brown       {1.5773502691896257e+00, 0, 0},
3539371c9d4SSatish Balay       {0.5,                    0, 0}
354b16ce868SStefano Zampini     };
355b16ce868SStefano Zampini     const PetscReal Gamma[3][3] = {
356b16ce868SStefano Zampini       {7.8867513459481287e-01,  0,                       0                     },
357b16ce868SStefano Zampini       {-1.5773502691896257e+00, 7.8867513459481287e-01,  0                     },
358b16ce868SStefano Zampini       {-6.7075317547305480e-01, -1.7075317547305482e-01, 7.8867513459481287e-01}
359b16ce868SStefano Zampini     };
360b16ce868SStefano Zampini     const PetscReal b[3]  = {1.0566243270259355e-01, 4.9038105676657971e-02, 8.4529946162074843e-01};
361b16ce868SStefano Zampini     const PetscReal b2[3] = {-1.7863279495408180e-01, 1. / 3., 8.4529946162074843e-01};
3621f80e275SEmil Constantinescu 
3631f80e275SEmil Constantinescu     binterpt[0][0] = -0.8094010767585034;
3641f80e275SEmil Constantinescu     binterpt[1][0] = -0.5;
3651f80e275SEmil Constantinescu     binterpt[2][0] = 2.3094010767585034;
3661f80e275SEmil Constantinescu     binterpt[0][1] = 0.9641016151377548;
3671f80e275SEmil Constantinescu     binterpt[1][1] = 0.5;
3681f80e275SEmil Constantinescu     binterpt[2][1] = -1.4641016151377548;
369bbd56ea5SKarl Rupp 
3709566063dSJacob Faibussowitsch     PetscCall(TSRosWRegister(TSROSWRA3PW, 3, 3, &A[0][0], &Gamma[0][0], b, b2, 2, &binterpt[0][0]));
371fe7e6d57SJed Brown   }
372fe7e6d57SJed Brown   {
3733ca35412SEmil Constantinescu     PetscReal binterpt[4][3];
374da80777bSKarl Rupp     /*const PetscReal g = 4.3586652150845900e-01; Directly written in-place below */
375b16ce868SStefano Zampini     const PetscReal A[4][4] = {
3769371c9d4SSatish Balay       {0,                      0,                       0,  0},
377fe7e6d57SJed Brown       {8.7173304301691801e-01, 0,                       0,  0},
378fe7e6d57SJed Brown       {8.4457060015369423e-01, -1.1299064236484185e-01, 0,  0},
3799371c9d4SSatish Balay       {0,                      0,                       1., 0}
380b16ce868SStefano Zampini     };
381b16ce868SStefano Zampini     const PetscReal Gamma[4][4] = {
382b16ce868SStefano Zampini       {4.3586652150845900e-01,  0,                       0,                      0                     },
383b16ce868SStefano Zampini       {-8.7173304301691801e-01, 4.3586652150845900e-01,  0,                      0                     },
384b16ce868SStefano Zampini       {-9.0338057013044082e-01, 5.4180672388095326e-02,  4.3586652150845900e-01, 0                     },
385b16ce868SStefano Zampini       {2.4212380706095346e-01,  -1.2232505839045147e+00, 5.4526025533510214e-01, 4.3586652150845900e-01}
386b16ce868SStefano Zampini     };
387b16ce868SStefano Zampini     const PetscReal b[4]  = {2.4212380706095346e-01, -1.2232505839045147e+00, 1.5452602553351020e+00, 4.3586652150845900e-01};
388b16ce868SStefano Zampini     const PetscReal b2[4] = {3.7810903145819369e-01, -9.6042292212423178e-02, 5.0000000000000000e-01, 2.1793326075422950e-01};
3893ca35412SEmil Constantinescu 
3903ca35412SEmil Constantinescu     binterpt[0][0] = 1.0564298455794094;
3913ca35412SEmil Constantinescu     binterpt[1][0] = 2.296429974281067;
3923ca35412SEmil Constantinescu     binterpt[2][0] = -1.307599564525376;
3933ca35412SEmil Constantinescu     binterpt[3][0] = -1.045260255335102;
3943ca35412SEmil Constantinescu     binterpt[0][1] = -1.3864882699759573;
3953ca35412SEmil Constantinescu     binterpt[1][1] = -8.262611700275677;
3963ca35412SEmil Constantinescu     binterpt[2][1] = 7.250979895056055;
3973ca35412SEmil Constantinescu     binterpt[3][1] = 2.398120075195581;
3983ca35412SEmil Constantinescu     binterpt[0][2] = 0.5721822314575016;
3993ca35412SEmil Constantinescu     binterpt[1][2] = 4.742931142090097;
4003ca35412SEmil Constantinescu     binterpt[2][2] = -4.398120075195578;
4013ca35412SEmil Constantinescu     binterpt[3][2] = -0.9169932983520199;
4023ca35412SEmil Constantinescu 
4039566063dSJacob Faibussowitsch     PetscCall(TSRosWRegister(TSROSWRA34PW2, 3, 4, &A[0][0], &Gamma[0][0], b, b2, 3, &binterpt[0][0]));
404e27a552bSJed Brown   }
405ef3c5b88SJed Brown   {
406da80777bSKarl Rupp     /* const PetscReal g = 0.5;       Directly written in-place below */
407b16ce868SStefano Zampini     const PetscReal A[4][4] = {
4089371c9d4SSatish Balay       {0,    0,     0,   0},
409ef3c5b88SJed Brown       {0,    0,     0,   0},
410ef3c5b88SJed Brown       {1.,   0,     0,   0},
4119371c9d4SSatish Balay       {0.75, -0.25, 0.5, 0}
412b16ce868SStefano Zampini     };
413b16ce868SStefano Zampini     const PetscReal Gamma[4][4] = {
414b16ce868SStefano Zampini       {0.5,     0,       0,       0  },
415b16ce868SStefano Zampini       {1.,      0.5,     0,       0  },
416b16ce868SStefano Zampini       {-0.25,   -0.25,   0.5,     0  },
417b16ce868SStefano Zampini       {1. / 12, 1. / 12, -2. / 3, 0.5}
418b16ce868SStefano Zampini     };
419b16ce868SStefano Zampini     const PetscReal b[4]  = {5. / 6, -1. / 6, -1. / 6, 0.5};
420b16ce868SStefano Zampini     const PetscReal b2[4] = {0.75, -0.25, 0.5, 0};
421bbd56ea5SKarl Rupp 
4229566063dSJacob Faibussowitsch     PetscCall(TSRosWRegister(TSROSWRODAS3, 3, 4, &A[0][0], &Gamma[0][0], b, b2, 0, NULL));
423ef3c5b88SJed Brown   }
424ef3c5b88SJed Brown   {
425*48665b53SJed Brown     /* const PetscReal g = 0.25;       Directly written in-place below */
426*48665b53SJed Brown     const PetscReal A[6][6] = {
427*48665b53SJed Brown       {0,                       0,                       0,                       0,                       0,    0},
428*48665b53SJed Brown       {0.75,                    0,                       0,                       0,                       0,    0},
429*48665b53SJed Brown       {7.5162877593868457e-02,  2.4837122406131545e-02,  0,                       0,                       0,    0},
430*48665b53SJed Brown       {1.6532708886396510e+00,  2.1545706385445562e-01,  -1.3157488872766792e+00, 0,                       0,    0},
431*48665b53SJed Brown       {1.9385003738039885e+01,  1.2007117225835324e+00,  -1.9337924059522791e+01, -2.4779140110062559e-01, 0,    0},
432*48665b53SJed Brown       {-7.3844531665375115e+00, -3.0593419030174646e-01, 7.8622074209377981e+00,  5.7817993590145966e-01,  0.25, 0}
433*48665b53SJed Brown     };
434*48665b53SJed Brown     const PetscReal Gamma[6][6] = {
435*48665b53SJed Brown       {0.25,                    0,                       0,                       0,                       0,                       0   },
436*48665b53SJed Brown       {-7.5000000000000000e-01, 0.25,                    0,                       0,                       0,                       0   },
437*48665b53SJed Brown       {-8.8644359075349941e-02, -2.8688974257983398e-02, 0.25,                    0,                       0,                       0   },
438*48665b53SJed Brown       {-4.8470034585330284e+00, -3.1583244269672095e-01, 4.9536568360123221e+00,  0.25,                    0,                       0   },
439*48665b53SJed Brown       {-2.6769456904577400e+01, -1.5066459128852787e+00, 2.7200131480460591e+01,  8.2597133700208525e-01,  0.25,                    0   },
440*48665b53SJed Brown       {6.5876206496361416e+00,  3.6807059172993878e-01,  -6.7423520694658121e+00, -1.0619631475741095e-01, -3.5714285714285715e-01, 0.25}
441*48665b53SJed Brown     };
442*48665b53SJed Brown     const PetscReal b[6]  = {-7.9683251690137014e-01, 6.2136401428192344e-02, 1.1198553514719862e+00, 4.7198362114404874e-01, -1.0714285714285714e-01, 0.25};
443*48665b53SJed Brown     const PetscReal b2[6] = {-7.3844531665375115e+00, -3.0593419030174646e-01, 7.8622074209377981e+00, 5.7817993590145966e-01, 0.25, 0.0};
444*48665b53SJed Brown 
445*48665b53SJed Brown     PetscCall(TSRosWRegister(TSROSWRODASPR, 4, 6, &A[0][0], &Gamma[0][0], b, b2, 0, NULL));
446*48665b53SJed Brown   }
447*48665b53SJed Brown   {
448da80777bSKarl Rupp     /*const PetscReal g = 0.43586652150845899941601945119356;       Directly written in-place below */
449b16ce868SStefano Zampini     const PetscReal A[3][3] = {
4509371c9d4SSatish Balay       {0,                                  0, 0},
451da80777bSKarl Rupp       {0.43586652150845899941601945119356, 0, 0},
4529371c9d4SSatish Balay       {0.43586652150845899941601945119356, 0, 0}
453b16ce868SStefano Zampini     };
454b16ce868SStefano Zampini     const PetscReal Gamma[3][3] = {
455b16ce868SStefano Zampini       {0.43586652150845899941601945119356,  0,                                  0                                 },
456b16ce868SStefano Zampini       {-0.19294655696029095575009695436041, 0.43586652150845899941601945119356, 0                                 },
457b16ce868SStefano Zampini       {0,                                   1.74927148125794685173529749738960, 0.43586652150845899941601945119356}
458b16ce868SStefano Zampini     };
459b16ce868SStefano Zampini     const PetscReal b[3]  = {-0.75457412385404315829818998646589, 1.94100407061964420292840123379419, -0.18642994676560104463021124732829};
460b16ce868SStefano Zampini     const PetscReal b2[3] = {-1.53358745784149585370766523913002, 2.81745131148625772213931745457622, -0.28386385364476186843165221544619};
4611f80e275SEmil Constantinescu 
4621f80e275SEmil Constantinescu     PetscReal binterpt[3][2];
4631f80e275SEmil Constantinescu     binterpt[0][0] = 3.793692883777660870425141387941;
4641f80e275SEmil Constantinescu     binterpt[1][0] = -2.918692883777660870425141387941;
4651f80e275SEmil Constantinescu     binterpt[2][0] = 0.125;
4661f80e275SEmil Constantinescu     binterpt[0][1] = -0.725741064379812106687651020584;
4671f80e275SEmil Constantinescu     binterpt[1][1] = 0.559074397713145440020984353917;
4681f80e275SEmil Constantinescu     binterpt[2][1] = 0.16666666666666666666666666666667;
4691f80e275SEmil Constantinescu 
4709566063dSJacob Faibussowitsch     PetscCall(TSRosWRegister(TSROSWSANDU3, 3, 3, &A[0][0], &Gamma[0][0], b, b2, 2, &binterpt[0][0]));
471ef3c5b88SJed Brown   }
472b1c69cc3SEmil Constantinescu   {
473da80777bSKarl Rupp     /*const PetscReal s3 = PetscSqrtReal(3.),g = (3.0+s3)/6.0;
474da80777bSKarl Rupp      * Direct evaluation: s3 = 1.732050807568877293527;
475da80777bSKarl Rupp      *                     g = 0.7886751345948128822546;
476da80777bSKarl Rupp      * Values are directly inserted below to ensure availability at compile time (compiler warnings otherwise...) */
477b16ce868SStefano Zampini     const PetscReal A[3][3] = {
4789371c9d4SSatish Balay       {0,    0,    0},
479b1c69cc3SEmil Constantinescu       {1,    0,    0},
4809371c9d4SSatish Balay       {0.25, 0.25, 0}
481b16ce868SStefano Zampini     };
482b16ce868SStefano Zampini     const PetscReal Gamma[3][3] = {
483b16ce868SStefano Zampini       {0,                                       0,                                      0                       },
484b16ce868SStefano Zampini       {(-3.0 - 1.732050807568877293527) / 6.0,  0.7886751345948128822546,               0                       },
485b16ce868SStefano Zampini       {(-3.0 - 1.732050807568877293527) / 24.0, (-3.0 - 1.732050807568877293527) / 8.0, 0.7886751345948128822546}
486b16ce868SStefano Zampini     };
487b16ce868SStefano Zampini     const PetscReal b[3]  = {1. / 6., 1. / 6., 2. / 3.};
488b16ce868SStefano Zampini     const PetscReal b2[3] = {1. / 4., 1. / 4., 1. / 2.};
489c0cb691aSEmil Constantinescu     PetscReal       binterpt[3][2];
490da80777bSKarl Rupp 
491c0cb691aSEmil Constantinescu     binterpt[0][0] = 0.089316397477040902157517886164709;
492c0cb691aSEmil Constantinescu     binterpt[1][0] = -0.91068360252295909784248211383529;
493c0cb691aSEmil Constantinescu     binterpt[2][0] = 1.8213672050459181956849642276706;
494c0cb691aSEmil Constantinescu     binterpt[0][1] = 0.077350269189625764509148780501957;
495c0cb691aSEmil Constantinescu     binterpt[1][1] = 1.077350269189625764509148780502;
496c0cb691aSEmil Constantinescu     binterpt[2][1] = -1.1547005383792515290182975610039;
497bbd56ea5SKarl Rupp 
4989566063dSJacob Faibussowitsch     PetscCall(TSRosWRegister(TSROSWASSP3P3S1C, 3, 3, &A[0][0], &Gamma[0][0], b, b2, 2, &binterpt[0][0]));
499b1c69cc3SEmil Constantinescu   }
500b1c69cc3SEmil Constantinescu 
501b1c69cc3SEmil Constantinescu   {
502b16ce868SStefano Zampini     const PetscReal A[4][4] = {
5039371c9d4SSatish Balay       {0,       0,       0,       0},
504b1c69cc3SEmil Constantinescu       {1. / 2., 0,       0,       0},
505b1c69cc3SEmil Constantinescu       {1. / 2., 1. / 2., 0,       0},
5069371c9d4SSatish Balay       {1. / 6., 1. / 6., 1. / 6., 0}
507b16ce868SStefano Zampini     };
508b16ce868SStefano Zampini     const PetscReal Gamma[4][4] = {
509b16ce868SStefano Zampini       {1. / 2., 0,        0,       0},
510b16ce868SStefano Zampini       {0.0,     1. / 4.,  0,       0},
511b16ce868SStefano Zampini       {-2.,     -2. / 3., 2. / 3., 0},
512b16ce868SStefano Zampini       {1. / 2., 5. / 36., -2. / 9, 0}
513b16ce868SStefano Zampini     };
514b16ce868SStefano Zampini     const PetscReal b[4]  = {1. / 6., 1. / 6., 1. / 6., 1. / 2.};
515b16ce868SStefano Zampini     const PetscReal b2[4] = {1. / 8., 3. / 4., 1. / 8., 0};
516c0cb691aSEmil Constantinescu     PetscReal       binterpt[4][3];
517da80777bSKarl Rupp 
518c0cb691aSEmil Constantinescu     binterpt[0][0] = 6.25;
519c0cb691aSEmil Constantinescu     binterpt[1][0] = -30.25;
520c0cb691aSEmil Constantinescu     binterpt[2][0] = 1.75;
521c0cb691aSEmil Constantinescu     binterpt[3][0] = 23.25;
522c0cb691aSEmil Constantinescu     binterpt[0][1] = -9.75;
523c0cb691aSEmil Constantinescu     binterpt[1][1] = 58.75;
524c0cb691aSEmil Constantinescu     binterpt[2][1] = -3.25;
525c0cb691aSEmil Constantinescu     binterpt[3][1] = -45.75;
526c0cb691aSEmil Constantinescu     binterpt[0][2] = 3.6666666666666666666666666666667;
527c0cb691aSEmil Constantinescu     binterpt[1][2] = -28.333333333333333333333333333333;
528c0cb691aSEmil Constantinescu     binterpt[2][2] = 1.6666666666666666666666666666667;
529c0cb691aSEmil Constantinescu     binterpt[3][2] = 23.;
530bbd56ea5SKarl Rupp 
5319566063dSJacob Faibussowitsch     PetscCall(TSRosWRegister(TSROSWLASSP3P4S2C, 3, 4, &A[0][0], &Gamma[0][0], b, b2, 3, &binterpt[0][0]));
532b1c69cc3SEmil Constantinescu   }
533b1c69cc3SEmil Constantinescu 
534b1c69cc3SEmil Constantinescu   {
535b16ce868SStefano Zampini     const PetscReal A[4][4] = {
5369371c9d4SSatish Balay       {0,       0,       0,       0},
537b1c69cc3SEmil Constantinescu       {1. / 2., 0,       0,       0},
538b1c69cc3SEmil Constantinescu       {1. / 2., 1. / 2., 0,       0},
5399371c9d4SSatish Balay       {1. / 6., 1. / 6., 1. / 6., 0}
540b16ce868SStefano Zampini     };
541b16ce868SStefano Zampini     const PetscReal Gamma[4][4] = {
542b16ce868SStefano Zampini       {1. / 2.,  0,          0,        0},
543b16ce868SStefano Zampini       {0.0,      3. / 4.,    0,        0},
544b16ce868SStefano Zampini       {-2. / 3., -23. / 9.,  2. / 9.,  0},
545b16ce868SStefano Zampini       {1. / 18., 65. / 108., -2. / 27, 0}
546b16ce868SStefano Zampini     };
547b16ce868SStefano Zampini     const PetscReal b[4]  = {1. / 6., 1. / 6., 1. / 6., 1. / 2.};
548b16ce868SStefano Zampini     const PetscReal b2[4] = {3. / 16., 10. / 16., 3. / 16., 0};
549c0cb691aSEmil Constantinescu     PetscReal       binterpt[4][3];
550da80777bSKarl Rupp 
551c0cb691aSEmil Constantinescu     binterpt[0][0] = 1.6911764705882352941176470588235;
552c0cb691aSEmil Constantinescu     binterpt[1][0] = 3.6813725490196078431372549019608;
553c0cb691aSEmil Constantinescu     binterpt[2][0] = 0.23039215686274509803921568627451;
554c0cb691aSEmil Constantinescu     binterpt[3][0] = -4.6029411764705882352941176470588;
555c0cb691aSEmil Constantinescu     binterpt[0][1] = -0.95588235294117647058823529411765;
556c0cb691aSEmil Constantinescu     binterpt[1][1] = -6.2401960784313725490196078431373;
557c0cb691aSEmil Constantinescu     binterpt[2][1] = -0.31862745098039215686274509803922;
558c0cb691aSEmil Constantinescu     binterpt[3][1] = 7.5147058823529411764705882352941;
559c0cb691aSEmil Constantinescu     binterpt[0][2] = -0.56862745098039215686274509803922;
560c0cb691aSEmil Constantinescu     binterpt[1][2] = 2.7254901960784313725490196078431;
561c0cb691aSEmil Constantinescu     binterpt[2][2] = 0.25490196078431372549019607843137;
562c0cb691aSEmil Constantinescu     binterpt[3][2] = -2.4117647058823529411764705882353;
563bbd56ea5SKarl Rupp 
5649566063dSJacob Faibussowitsch     PetscCall(TSRosWRegister(TSROSWLLSSP3P4S2C, 3, 4, &A[0][0], &Gamma[0][0], b, b2, 3, &binterpt[0][0]));
565b1c69cc3SEmil Constantinescu   }
566753f8adbSEmil Constantinescu 
567753f8adbSEmil Constantinescu   {
568753f8adbSEmil Constantinescu     PetscReal A[4][4], Gamma[4][4], b[4], b2[4];
5693ca35412SEmil Constantinescu     PetscReal binterpt[4][3];
570753f8adbSEmil Constantinescu 
571753f8adbSEmil Constantinescu     Gamma[0][0] = 0.4358665215084589994160194475295062513822671686978816;
5729371c9d4SSatish Balay     Gamma[0][1] = 0;
5739371c9d4SSatish Balay     Gamma[0][2] = 0;
5749371c9d4SSatish Balay     Gamma[0][3] = 0;
575753f8adbSEmil Constantinescu     Gamma[1][0] = -1.997527830934941248426324674704153457289527280554476;
576753f8adbSEmil Constantinescu     Gamma[1][1] = 0.4358665215084589994160194475295062513822671686978816;
5779371c9d4SSatish Balay     Gamma[1][2] = 0;
5789371c9d4SSatish Balay     Gamma[1][3] = 0;
579753f8adbSEmil Constantinescu     Gamma[2][0] = -1.007948511795029620852002345345404191008352770119903;
580753f8adbSEmil Constantinescu     Gamma[2][1] = -0.004648958462629345562774289390054679806993396798458131;
581753f8adbSEmil Constantinescu     Gamma[2][2] = 0.4358665215084589994160194475295062513822671686978816;
58205e8e825SJed Brown     Gamma[2][3] = 0;
583753f8adbSEmil Constantinescu     Gamma[3][0] = -0.6685429734233467180451604600279552604364311322650783;
584753f8adbSEmil Constantinescu     Gamma[3][1] = 0.6056625986449338476089525334450053439525178740492984;
585753f8adbSEmil Constantinescu     Gamma[3][2] = -0.9717899277217721234705114616271378792182450260943198;
586753f8adbSEmil Constantinescu     Gamma[3][3] = 0;
587753f8adbSEmil Constantinescu 
5889371c9d4SSatish Balay     A[0][0] = 0;
5899371c9d4SSatish Balay     A[0][1] = 0;
5909371c9d4SSatish Balay     A[0][2] = 0;
5919371c9d4SSatish Balay     A[0][3] = 0;
592753f8adbSEmil Constantinescu     A[1][0] = 0.8717330430169179988320388950590125027645343373957631;
5939371c9d4SSatish Balay     A[1][1] = 0;
5949371c9d4SSatish Balay     A[1][2] = 0;
5959371c9d4SSatish Balay     A[1][3] = 0;
596753f8adbSEmil Constantinescu     A[2][0] = 0.5275890119763004115618079766722914408876108660811028;
597753f8adbSEmil Constantinescu     A[2][1] = 0.07241098802369958843819203208518599088698057726988732;
5989371c9d4SSatish Balay     A[2][2] = 0;
5999371c9d4SSatish Balay     A[2][3] = 0;
600753f8adbSEmil Constantinescu     A[3][0] = 0.3990960076760701320627260685975778145384666450351314;
601753f8adbSEmil Constantinescu     A[3][1] = -0.4375576546135194437228463747348862825846903771419953;
602753f8adbSEmil Constantinescu     A[3][2] = 1.038461646937449311660120300601880176655352737312713;
60305e8e825SJed Brown     A[3][3] = 0;
604753f8adbSEmil Constantinescu 
605753f8adbSEmil Constantinescu     b[0] = 0.1876410243467238251612921333138006734899663569186926;
606753f8adbSEmil Constantinescu     b[1] = -0.5952974735769549480478230473706443582188442040780541;
607753f8adbSEmil Constantinescu     b[2] = 0.9717899277217721234705114616271378792182450260943198;
608753f8adbSEmil Constantinescu     b[3] = 0.4358665215084589994160194475295062513822671686978816;
609753f8adbSEmil Constantinescu 
610753f8adbSEmil Constantinescu     b2[0] = 0.2147402862233891404862383521089097657790734483804460;
611753f8adbSEmil Constantinescu     b2[1] = -0.4851622638849390928209050538171743017757490232519684;
612753f8adbSEmil Constantinescu     b2[2] = 0.8687250025203875511662123688667549217531982787600080;
613753f8adbSEmil Constantinescu     b2[3] = 0.4016969751411624011684543450940068201770721128357014;
614753f8adbSEmil Constantinescu 
6153ca35412SEmil Constantinescu     binterpt[0][0] = 2.2565812720167954547104627844105;
6163ca35412SEmil Constantinescu     binterpt[1][0] = 1.349166413351089573796243820819;
6173ca35412SEmil Constantinescu     binterpt[2][0] = -2.4695174540533503758652847586647;
6183ca35412SEmil Constantinescu     binterpt[3][0] = -0.13623023131453465264142184656474;
6193ca35412SEmil Constantinescu     binterpt[0][1] = -3.0826699111559187902922463354557;
6203ca35412SEmil Constantinescu     binterpt[1][1] = -2.4689115685996042534544925650515;
6213ca35412SEmil Constantinescu     binterpt[2][1] = 5.7428279814696677152129332773553;
6223ca35412SEmil Constantinescu     binterpt[3][1] = -0.19124650171414467146619437684812;
6233ca35412SEmil Constantinescu     binterpt[0][2] = 1.0137296634858471607430756831148;
6243ca35412SEmil Constantinescu     binterpt[1][2] = 0.52444768167155973161042570784064;
6253ca35412SEmil Constantinescu     binterpt[2][2] = -2.3015205996945452158771370439586;
6263ca35412SEmil Constantinescu     binterpt[3][2] = 0.76334325453713832352363565300308;
627f4aed992SEmil Constantinescu 
6289566063dSJacob Faibussowitsch     PetscCall(TSRosWRegister(TSROSWARK3, 3, 4, &A[0][0], &Gamma[0][0], b, b2, 3, &binterpt[0][0]));
629753f8adbSEmil Constantinescu   }
6309566063dSJacob Faibussowitsch   PetscCall(TSRosWRegisterRos4(TSROSWGRK4T, 0.231, PETSC_DEFAULT, PETSC_DEFAULT, 0, -0.1282612945269037e+01));
6319566063dSJacob Faibussowitsch   PetscCall(TSRosWRegisterRos4(TSROSWSHAMP4, 0.5, PETSC_DEFAULT, PETSC_DEFAULT, 0, 125. / 108.));
6329566063dSJacob Faibussowitsch   PetscCall(TSRosWRegisterRos4(TSROSWVELDD4, 0.22570811482256823492, PETSC_DEFAULT, PETSC_DEFAULT, 0, -1.355958941201148));
6339566063dSJacob Faibussowitsch   PetscCall(TSRosWRegisterRos4(TSROSW4L, 0.57282, PETSC_DEFAULT, PETSC_DEFAULT, 0, -1.093502252409163));
6343ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
635e27a552bSJed Brown }
636e27a552bSJed Brown 
637e27a552bSJed Brown /*@C
638bcf0153eSBarry Smith   TSRosWRegisterDestroy - Frees the list of schemes that were registered by `TSRosWRegister()`.
639e27a552bSJed Brown 
640e27a552bSJed Brown   Not Collective
641e27a552bSJed Brown 
642e27a552bSJed Brown   Level: advanced
643e27a552bSJed Brown 
6441cc06b55SBarry Smith .seealso: [](ch_ts), `TSRosWRegister()`, `TSRosWRegisterAll()`
645e27a552bSJed Brown @*/
646d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRosWRegisterDestroy(void)
647d71ae5a4SJacob Faibussowitsch {
64861692a83SJed Brown   RosWTableauLink link;
649e27a552bSJed Brown 
650e27a552bSJed Brown   PetscFunctionBegin;
65161692a83SJed Brown   while ((link = RosWTableauList)) {
65261692a83SJed Brown     RosWTableau t   = &link->tab;
65361692a83SJed Brown     RosWTableauList = link->next;
6549566063dSJacob Faibussowitsch     PetscCall(PetscFree5(t->A, t->Gamma, t->b, t->ASum, t->GammaSum));
6559566063dSJacob Faibussowitsch     PetscCall(PetscFree5(t->At, t->bt, t->GammaInv, t->GammaZeroDiag, t->GammaExplicitCorr));
6569566063dSJacob Faibussowitsch     PetscCall(PetscFree2(t->bembed, t->bembedt));
6579566063dSJacob Faibussowitsch     PetscCall(PetscFree(t->binterpt));
6589566063dSJacob Faibussowitsch     PetscCall(PetscFree(t->name));
6599566063dSJacob Faibussowitsch     PetscCall(PetscFree(link));
660e27a552bSJed Brown   }
661e27a552bSJed Brown   TSRosWRegisterAllCalled = PETSC_FALSE;
6623ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
663e27a552bSJed Brown }
664e27a552bSJed Brown 
665e27a552bSJed Brown /*@C
666bcf0153eSBarry Smith   TSRosWInitializePackage - This function initializes everything in the `TSROSW` package. It is called
667bcf0153eSBarry Smith   from `TSInitializePackage()`.
668e27a552bSJed Brown 
669e27a552bSJed Brown   Level: developer
670e27a552bSJed Brown 
6711cc06b55SBarry Smith .seealso: [](ch_ts), `TSROSW`, `PetscInitialize()`, `TSRosWFinalizePackage()`
672e27a552bSJed Brown @*/
673d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRosWInitializePackage(void)
674d71ae5a4SJacob Faibussowitsch {
675e27a552bSJed Brown   PetscFunctionBegin;
6763ba16761SJacob Faibussowitsch   if (TSRosWPackageInitialized) PetscFunctionReturn(PETSC_SUCCESS);
677e27a552bSJed Brown   TSRosWPackageInitialized = PETSC_TRUE;
6789566063dSJacob Faibussowitsch   PetscCall(TSRosWRegisterAll());
6799566063dSJacob Faibussowitsch   PetscCall(PetscRegisterFinalize(TSRosWFinalizePackage));
6803ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
681e27a552bSJed Brown }
682e27a552bSJed Brown 
683e27a552bSJed Brown /*@C
684bcf0153eSBarry Smith   TSRosWFinalizePackage - This function destroys everything in the `TSROSW` package. It is
685bcf0153eSBarry Smith   called from `PetscFinalize()`.
686e27a552bSJed Brown 
687e27a552bSJed Brown   Level: developer
688e27a552bSJed Brown 
6891cc06b55SBarry Smith .seealso: [](ch_ts), `TSROSW`, `PetscFinalize()`, `TSRosWInitializePackage()`
690e27a552bSJed Brown @*/
691d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRosWFinalizePackage(void)
692d71ae5a4SJacob Faibussowitsch {
693e27a552bSJed Brown   PetscFunctionBegin;
694e27a552bSJed Brown   TSRosWPackageInitialized = PETSC_FALSE;
6959566063dSJacob Faibussowitsch   PetscCall(TSRosWRegisterDestroy());
6963ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
697e27a552bSJed Brown }
698e27a552bSJed Brown 
699e27a552bSJed Brown /*@C
700bcf0153eSBarry Smith   TSRosWRegister - register a `TSROSW`, Rosenbrock W scheme by providing the entries in the Butcher tableau and optionally embedded approximations and interpolation
701e27a552bSJed Brown 
702e27a552bSJed Brown   Not Collective, but the same schemes should be registered on all processes on which they will be used
703e27a552bSJed Brown 
704e27a552bSJed Brown   Input Parameters:
705e27a552bSJed Brown + name     - identifier for method
706e27a552bSJed Brown . order    - approximation order of method
707e27a552bSJed Brown . s        - number of stages, this is the dimension of the matrices below
70861692a83SJed Brown . A        - Table of propagated stage coefficients (dimension s*s, row-major), strictly lower triangular
70961692a83SJed Brown . Gamma    - Table of coefficients in implicit stage equations (dimension s*s, row-major), lower triangular with nonzero diagonal
710fe7e6d57SJed Brown . b        - Step completion table (dimension s)
7110298fd71SBarry Smith . bembed   - Step completion table for a scheme of order one less (dimension s, NULL if no embedded scheme is available)
712f4aed992SEmil Constantinescu . pinterp  - Order of the interpolation scheme, equal to the number of columns of binterpt
71342faf41dSJed Brown - binterpt - Coefficients of the interpolation formula (dimension s*pinterp)
714e27a552bSJed Brown 
715e27a552bSJed Brown   Level: advanced
716e27a552bSJed Brown 
717bcf0153eSBarry Smith   Note:
718bcf0153eSBarry Smith   Several Rosenbrock W methods are provided, this function is only needed to create new methods.
719bcf0153eSBarry Smith 
7201cc06b55SBarry Smith .seealso: [](ch_ts), `TSROSW`
721e27a552bSJed Brown @*/
722d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRosWRegister(TSRosWType name, PetscInt order, PetscInt s, const PetscReal A[], const PetscReal Gamma[], const PetscReal b[], const PetscReal bembed[], PetscInt pinterp, const PetscReal binterpt[])
723d71ae5a4SJacob Faibussowitsch {
72461692a83SJed Brown   RosWTableauLink link;
72561692a83SJed Brown   RosWTableau     t;
72661692a83SJed Brown   PetscInt        i, j, k;
72761692a83SJed Brown   PetscScalar    *GammaInv;
728e27a552bSJed Brown 
729e27a552bSJed Brown   PetscFunctionBegin;
7304f572ea9SToby Isaac   PetscAssertPointer(name, 1);
7314f572ea9SToby Isaac   PetscAssertPointer(A, 4);
7324f572ea9SToby Isaac   PetscAssertPointer(Gamma, 5);
7334f572ea9SToby Isaac   PetscAssertPointer(b, 6);
7344f572ea9SToby Isaac   if (bembed) PetscAssertPointer(bembed, 7);
735fe7e6d57SJed Brown 
7369566063dSJacob Faibussowitsch   PetscCall(TSRosWInitializePackage());
7379566063dSJacob Faibussowitsch   PetscCall(PetscNew(&link));
738e27a552bSJed Brown   t = &link->tab;
7399566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(name, &t->name));
740e27a552bSJed Brown   t->order = order;
741e27a552bSJed Brown   t->s     = s;
7429566063dSJacob Faibussowitsch   PetscCall(PetscMalloc5(s * s, &t->A, s * s, &t->Gamma, s, &t->b, s, &t->ASum, s, &t->GammaSum));
7439566063dSJacob Faibussowitsch   PetscCall(PetscMalloc5(s * s, &t->At, s, &t->bt, s * s, &t->GammaInv, s, &t->GammaZeroDiag, s * s, &t->GammaExplicitCorr));
7449566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(t->A, A, s * s));
7459566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(t->Gamma, Gamma, s * s));
7469566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(t->GammaExplicitCorr, Gamma, s * s));
7479566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(t->b, b, s));
748fe7e6d57SJed Brown   if (bembed) {
7499566063dSJacob Faibussowitsch     PetscCall(PetscMalloc2(s, &t->bembed, s, &t->bembedt));
7509566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(t->bembed, bembed, s));
751fe7e6d57SJed Brown   }
75261692a83SJed Brown   for (i = 0; i < s; i++) {
75361692a83SJed Brown     t->ASum[i]     = 0;
75461692a83SJed Brown     t->GammaSum[i] = 0;
75561692a83SJed Brown     for (j = 0; j < s; j++) {
75661692a83SJed Brown       t->ASum[i] += A[i * s + j];
757fe7e6d57SJed Brown       t->GammaSum[i] += Gamma[i * s + j];
75861692a83SJed Brown     }
75961692a83SJed Brown   }
7609566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(s * s, &GammaInv)); /* Need to use Scalar for inverse, then convert back to Real */
76161692a83SJed Brown   for (i = 0; i < s * s; i++) GammaInv[i] = Gamma[i];
762fd96d5b0SEmil Constantinescu   for (i = 0; i < s; i++) {
763fd96d5b0SEmil Constantinescu     if (Gamma[i * s + i] == 0.0) {
764fd96d5b0SEmil Constantinescu       GammaInv[i * s + i] = 1.0;
765c17803e7SJed Brown       t->GammaZeroDiag[i] = PETSC_TRUE;
766fd96d5b0SEmil Constantinescu     } else {
767c17803e7SJed Brown       t->GammaZeroDiag[i] = PETSC_FALSE;
768fd96d5b0SEmil Constantinescu     }
769fd96d5b0SEmil Constantinescu   }
770fd96d5b0SEmil Constantinescu 
77161692a83SJed Brown   switch (s) {
772d71ae5a4SJacob Faibussowitsch   case 1:
773d71ae5a4SJacob Faibussowitsch     GammaInv[0] = 1. / GammaInv[0];
774d71ae5a4SJacob Faibussowitsch     break;
775d71ae5a4SJacob Faibussowitsch   case 2:
776d71ae5a4SJacob Faibussowitsch     PetscCall(PetscKernel_A_gets_inverse_A_2(GammaInv, 0, PETSC_FALSE, NULL));
777d71ae5a4SJacob Faibussowitsch     break;
778d71ae5a4SJacob Faibussowitsch   case 3:
779d71ae5a4SJacob Faibussowitsch     PetscCall(PetscKernel_A_gets_inverse_A_3(GammaInv, 0, PETSC_FALSE, NULL));
780d71ae5a4SJacob Faibussowitsch     break;
781d71ae5a4SJacob Faibussowitsch   case 4:
782d71ae5a4SJacob Faibussowitsch     PetscCall(PetscKernel_A_gets_inverse_A_4(GammaInv, 0, PETSC_FALSE, NULL));
783d71ae5a4SJacob Faibussowitsch     break;
78461692a83SJed Brown   case 5: {
78561692a83SJed Brown     PetscInt  ipvt5[5];
78661692a83SJed Brown     MatScalar work5[5 * 5];
7879371c9d4SSatish Balay     PetscCall(PetscKernel_A_gets_inverse_A_5(GammaInv, ipvt5, work5, 0, PETSC_FALSE, NULL));
7889371c9d4SSatish Balay     break;
78961692a83SJed Brown   }
790d71ae5a4SJacob Faibussowitsch   case 6:
791d71ae5a4SJacob Faibussowitsch     PetscCall(PetscKernel_A_gets_inverse_A_6(GammaInv, 0, PETSC_FALSE, NULL));
792d71ae5a4SJacob Faibussowitsch     break;
793d71ae5a4SJacob Faibussowitsch   case 7:
794d71ae5a4SJacob Faibussowitsch     PetscCall(PetscKernel_A_gets_inverse_A_7(GammaInv, 0, PETSC_FALSE, NULL));
795d71ae5a4SJacob Faibussowitsch     break;
796d71ae5a4SJacob Faibussowitsch   default:
797d71ae5a4SJacob Faibussowitsch     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Not implemented for %" PetscInt_FMT " stages", s);
79861692a83SJed Brown   }
79961692a83SJed Brown   for (i = 0; i < s * s; i++) t->GammaInv[i] = PetscRealPart(GammaInv[i]);
8009566063dSJacob Faibussowitsch   PetscCall(PetscFree(GammaInv));
80143b21953SEmil Constantinescu 
80243b21953SEmil Constantinescu   for (i = 0; i < s; i++) {
80343b21953SEmil Constantinescu     for (k = 0; k < i + 1; k++) {
80443b21953SEmil Constantinescu       t->GammaExplicitCorr[i * s + k] = (t->GammaExplicitCorr[i * s + k]) * (t->GammaInv[k * s + k]);
805ad540459SPierre Jolivet       for (j = k + 1; j < i + 1; j++) t->GammaExplicitCorr[i * s + k] += (t->GammaExplicitCorr[i * s + j]) * (t->GammaInv[j * s + k]);
80643b21953SEmil Constantinescu     }
80743b21953SEmil Constantinescu   }
80843b21953SEmil Constantinescu 
80961692a83SJed Brown   for (i = 0; i < s; i++) {
81061692a83SJed Brown     for (j = 0; j < s; j++) {
81161692a83SJed Brown       t->At[i * s + j] = 0;
812ad540459SPierre Jolivet       for (k = 0; k < s; k++) t->At[i * s + j] += t->A[i * s + k] * t->GammaInv[k * s + j];
81361692a83SJed Brown     }
81461692a83SJed Brown     t->bt[i] = 0;
815ad540459SPierre Jolivet     for (j = 0; j < s; j++) t->bt[i] += t->b[j] * t->GammaInv[j * s + i];
816fe7e6d57SJed Brown     if (bembed) {
817fe7e6d57SJed Brown       t->bembedt[i] = 0;
818ad540459SPierre Jolivet       for (j = 0; j < s; j++) t->bembedt[i] += t->bembed[j] * t->GammaInv[j * s + i];
819fe7e6d57SJed Brown     }
82061692a83SJed Brown   }
8218d59e960SJed Brown   t->ccfl = 1.0; /* Fix this */
8228d59e960SJed Brown 
823f4aed992SEmil Constantinescu   t->pinterp = pinterp;
8249566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(s * pinterp, &t->binterpt));
8259566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(t->binterpt, binterpt, s * pinterp));
82661692a83SJed Brown   link->next      = RosWTableauList;
82761692a83SJed Brown   RosWTableauList = link;
8283ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
829e27a552bSJed Brown }
830e27a552bSJed Brown 
83142faf41dSJed Brown /*@C
832fd292e60Sprj-   TSRosWRegisterRos4 - register a fourth order Rosenbrock scheme by providing parameter choices
83342faf41dSJed Brown 
83442faf41dSJed Brown   Not Collective, but the same schemes should be registered on all processes on which they will be used
83542faf41dSJed Brown 
83642faf41dSJed Brown   Input Parameters:
83742faf41dSJed Brown + name  - identifier for method
83842faf41dSJed Brown . gamma - leading coefficient (diagonal entry)
83942faf41dSJed Brown . a2    - design parameter, see Table 7.2 of Hairer&Wanner
84042faf41dSJed Brown . a3    - design parameter or PETSC_DEFAULT to satisfy one of the order five conditions (Eq 7.22)
84142faf41dSJed Brown . b3    - design parameter, see Table 7.2 of Hairer&Wanner
842a2b725a8SWilliam Gropp - e4    - design parameter for embedded method, see coefficient E4 in ros4.f code from Hairer
84342faf41dSJed Brown 
844bcf0153eSBarry Smith   Level: developer
845bcf0153eSBarry Smith 
84642faf41dSJed Brown   Notes:
84742faf41dSJed Brown   This routine encodes the design of fourth order Rosenbrock methods as described in Hairer and Wanner volume 2.
84842faf41dSJed Brown   It is used here to implement several methods from the book and can be used to experiment with new methods.
84942faf41dSJed Brown   It was written this way instead of by copying coefficients in order to provide better than double precision satisfaction of the order conditions.
85042faf41dSJed Brown 
8511cc06b55SBarry Smith .seealso: [](ch_ts), `TSRosW`, `TSRosWRegister()`
85242faf41dSJed Brown @*/
853d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRosWRegisterRos4(TSRosWType name, PetscReal gamma, PetscReal a2, PetscReal a3, PetscReal b3, PetscReal e4)
854d71ae5a4SJacob Faibussowitsch {
85542faf41dSJed Brown   /* Declare numeric constants so they can be quad precision without being truncated at double */
8569371c9d4SSatish Balay   const PetscReal one = 1, two = 2, three = 3, four = 4, five = 5, six = 6, eight = 8, twelve = 12, twenty = 20, twentyfour = 24, p32 = one / six - gamma + gamma * gamma, p42 = one / eight - gamma / three, p43 = one / twelve - gamma / three, p44 = one / twentyfour - gamma / two + three / two * gamma * gamma - gamma * gamma * gamma, p56 = one / twenty - gamma / four;
85742faf41dSJed Brown   PetscReal   a4, a32, a42, a43, b1, b2, b4, beta2p, beta3p, beta4p, beta32, beta42, beta43, beta32beta2p, beta4jbetajp;
85842faf41dSJed Brown   PetscReal   A[4][4], Gamma[4][4], b[4], bm[4];
85942faf41dSJed Brown   PetscScalar M[3][3], rhs[3];
86042faf41dSJed Brown 
86142faf41dSJed Brown   PetscFunctionBegin;
86242faf41dSJed Brown   /* Step 1: choose Gamma (input) */
86342faf41dSJed Brown   /* Step 2: choose a2,a3,a4; b1,b2,b3,b4 to satisfy order conditions */
86413bcc0bdSJacob Faibussowitsch   if (a3 == (PetscReal)PETSC_DEFAULT) a3 = (one / five - a2 / four) / (one / four - a2 / three); /* Eq 7.22 */
86542faf41dSJed Brown   a4 = a3;                                                                                       /* consequence of 7.20 */
86642faf41dSJed Brown 
86742faf41dSJed Brown   /* Solve order conditions 7.15a, 7.15c, 7.15e */
8689371c9d4SSatish Balay   M[0][0] = one;
8699371c9d4SSatish Balay   M[0][1] = one;
8709371c9d4SSatish Balay   M[0][2] = one; /* 7.15a */
8719371c9d4SSatish Balay   M[1][0] = 0.0;
8729371c9d4SSatish Balay   M[1][1] = a2 * a2;
8739371c9d4SSatish Balay   M[1][2] = a4 * a4; /* 7.15c */
8749371c9d4SSatish Balay   M[2][0] = 0.0;
8759371c9d4SSatish Balay   M[2][1] = a2 * a2 * a2;
8769371c9d4SSatish Balay   M[2][2] = a4 * a4 * a4; /* 7.15e */
87742faf41dSJed Brown   rhs[0]  = one - b3;
87842faf41dSJed Brown   rhs[1]  = one / three - a3 * a3 * b3;
87942faf41dSJed Brown   rhs[2]  = one / four - a3 * a3 * a3 * b3;
8809566063dSJacob Faibussowitsch   PetscCall(PetscKernel_A_gets_inverse_A_3(&M[0][0], 0, PETSC_FALSE, NULL));
88142faf41dSJed Brown   b1 = PetscRealPart(M[0][0] * rhs[0] + M[0][1] * rhs[1] + M[0][2] * rhs[2]);
88242faf41dSJed Brown   b2 = PetscRealPart(M[1][0] * rhs[0] + M[1][1] * rhs[1] + M[1][2] * rhs[2]);
88342faf41dSJed Brown   b4 = PetscRealPart(M[2][0] * rhs[0] + M[2][1] * rhs[1] + M[2][2] * rhs[2]);
88442faf41dSJed Brown 
88542faf41dSJed Brown   /* Step 3 */
88642faf41dSJed Brown   beta43       = (p56 - a2 * p43) / (b4 * a3 * a3 * (a3 - a2)); /* 7.21 */
88742faf41dSJed Brown   beta32beta2p = p44 / (b4 * beta43);                           /* 7.15h */
88842faf41dSJed Brown   beta4jbetajp = (p32 - b3 * beta32beta2p) / b4;
8899371c9d4SSatish Balay   M[0][0]      = b2;
8909371c9d4SSatish Balay   M[0][1]      = b3;
8919371c9d4SSatish Balay   M[0][2]      = b4;
8929371c9d4SSatish Balay   M[1][0]      = a4 * a4 * beta32beta2p - a3 * a3 * beta4jbetajp;
8939371c9d4SSatish Balay   M[1][1]      = a2 * a2 * beta4jbetajp;
8949371c9d4SSatish Balay   M[1][2]      = -a2 * a2 * beta32beta2p;
8959371c9d4SSatish Balay   M[2][0]      = b4 * beta43 * a3 * a3 - p43;
8969371c9d4SSatish Balay   M[2][1]      = -b4 * beta43 * a2 * a2;
8979371c9d4SSatish Balay   M[2][2]      = 0;
8989371c9d4SSatish Balay   rhs[0]       = one / two - gamma;
8999371c9d4SSatish Balay   rhs[1]       = 0;
9009371c9d4SSatish Balay   rhs[2]       = -a2 * a2 * p32;
9019566063dSJacob Faibussowitsch   PetscCall(PetscKernel_A_gets_inverse_A_3(&M[0][0], 0, PETSC_FALSE, NULL));
90242faf41dSJed Brown   beta2p = PetscRealPart(M[0][0] * rhs[0] + M[0][1] * rhs[1] + M[0][2] * rhs[2]);
90342faf41dSJed Brown   beta3p = PetscRealPart(M[1][0] * rhs[0] + M[1][1] * rhs[1] + M[1][2] * rhs[2]);
90442faf41dSJed Brown   beta4p = PetscRealPart(M[2][0] * rhs[0] + M[2][1] * rhs[1] + M[2][2] * rhs[2]);
90542faf41dSJed Brown 
90642faf41dSJed Brown   /* Step 4: back-substitute */
90742faf41dSJed Brown   beta32 = beta32beta2p / beta2p;
90842faf41dSJed Brown   beta42 = (beta4jbetajp - beta43 * beta3p) / beta2p;
90942faf41dSJed Brown 
91042faf41dSJed Brown   /* Step 5: 7.15f and 7.20, then 7.16 */
91142faf41dSJed Brown   a43 = 0;
91242faf41dSJed Brown   a32 = p42 / (b3 * a3 * beta2p + b4 * a4 * beta2p);
91342faf41dSJed Brown   a42 = a32;
91442faf41dSJed Brown 
9159371c9d4SSatish Balay   A[0][0]     = 0;
9169371c9d4SSatish Balay   A[0][1]     = 0;
9179371c9d4SSatish Balay   A[0][2]     = 0;
9189371c9d4SSatish Balay   A[0][3]     = 0;
9199371c9d4SSatish Balay   A[1][0]     = a2;
9209371c9d4SSatish Balay   A[1][1]     = 0;
9219371c9d4SSatish Balay   A[1][2]     = 0;
9229371c9d4SSatish Balay   A[1][3]     = 0;
9239371c9d4SSatish Balay   A[2][0]     = a3 - a32;
9249371c9d4SSatish Balay   A[2][1]     = a32;
9259371c9d4SSatish Balay   A[2][2]     = 0;
9269371c9d4SSatish Balay   A[2][3]     = 0;
9279371c9d4SSatish Balay   A[3][0]     = a4 - a43 - a42;
9289371c9d4SSatish Balay   A[3][1]     = a42;
9299371c9d4SSatish Balay   A[3][2]     = a43;
9309371c9d4SSatish Balay   A[3][3]     = 0;
9319371c9d4SSatish Balay   Gamma[0][0] = gamma;
9329371c9d4SSatish Balay   Gamma[0][1] = 0;
9339371c9d4SSatish Balay   Gamma[0][2] = 0;
9349371c9d4SSatish Balay   Gamma[0][3] = 0;
9359371c9d4SSatish Balay   Gamma[1][0] = beta2p - A[1][0];
9369371c9d4SSatish Balay   Gamma[1][1] = gamma;
9379371c9d4SSatish Balay   Gamma[1][2] = 0;
9389371c9d4SSatish Balay   Gamma[1][3] = 0;
9399371c9d4SSatish Balay   Gamma[2][0] = beta3p - beta32 - A[2][0];
9409371c9d4SSatish Balay   Gamma[2][1] = beta32 - A[2][1];
9419371c9d4SSatish Balay   Gamma[2][2] = gamma;
9429371c9d4SSatish Balay   Gamma[2][3] = 0;
9439371c9d4SSatish Balay   Gamma[3][0] = beta4p - beta42 - beta43 - A[3][0];
9449371c9d4SSatish Balay   Gamma[3][1] = beta42 - A[3][1];
9459371c9d4SSatish Balay   Gamma[3][2] = beta43 - A[3][2];
9469371c9d4SSatish Balay   Gamma[3][3] = gamma;
9479371c9d4SSatish Balay   b[0]        = b1;
9489371c9d4SSatish Balay   b[1]        = b2;
9499371c9d4SSatish Balay   b[2]        = b3;
9509371c9d4SSatish Balay   b[3]        = b4;
95142faf41dSJed Brown 
95242faf41dSJed Brown   /* Construct embedded formula using given e4. We are solving Equation 7.18. */
95342faf41dSJed Brown   bm[3] = b[3] - e4 * gamma;                                              /* using definition of E4 */
95442faf41dSJed Brown   bm[2] = (p32 - beta4jbetajp * bm[3]) / (beta32 * beta2p);               /* fourth row of 7.18 */
95542faf41dSJed Brown   bm[1] = (one / two - gamma - beta3p * bm[2] - beta4p * bm[3]) / beta2p; /* second row */
95642faf41dSJed Brown   bm[0] = one - bm[1] - bm[2] - bm[3];                                    /* first row */
95742faf41dSJed Brown 
95842faf41dSJed Brown   {
95942faf41dSJed Brown     const PetscReal misfit = a2 * a2 * bm[1] + a3 * a3 * bm[2] + a4 * a4 * bm[3] - one / three;
9603c633725SBarry Smith     PetscCheck(PetscAbs(misfit) <= PETSC_SMALL, PETSC_COMM_SELF, PETSC_ERR_SUP, "Assumptions violated, could not construct a third order embedded method");
96142faf41dSJed Brown   }
9629566063dSJacob Faibussowitsch   PetscCall(TSRosWRegister(name, 4, 4, &A[0][0], &Gamma[0][0], b, bm, 0, NULL));
9633ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
96442faf41dSJed Brown }
96542faf41dSJed Brown 
9661c3436cfSJed Brown /*
9671c3436cfSJed Brown  The step completion formula is
9681c3436cfSJed Brown 
9691c3436cfSJed Brown  x1 = x0 + b^T Y
9701c3436cfSJed Brown 
9711c3436cfSJed Brown  where Y is the multi-vector of stages corrections. This function can be called before or after ts->vec_sol has been
9721c3436cfSJed Brown  updated. Suppose we have a completion formula b and an embedded formula be of different order. We can write
9731c3436cfSJed Brown 
9741c3436cfSJed Brown  x1e = x0 + be^T Y
9751c3436cfSJed Brown      = x1 - b^T Y + be^T Y
9761c3436cfSJed Brown      = x1 + (be - b)^T Y
9771c3436cfSJed Brown 
9781c3436cfSJed Brown  so we can evaluate the method of different order even after the step has been optimistically completed.
9791c3436cfSJed Brown */
980d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSEvaluateStep_RosW(TS ts, PetscInt order, Vec U, PetscBool *done)
981d71ae5a4SJacob Faibussowitsch {
9821c3436cfSJed Brown   TS_RosW     *ros = (TS_RosW *)ts->data;
9831c3436cfSJed Brown   RosWTableau  tab = ros->tableau;
9841c3436cfSJed Brown   PetscScalar *w   = ros->work;
9851c3436cfSJed Brown   PetscInt     i;
9861c3436cfSJed Brown 
9871c3436cfSJed Brown   PetscFunctionBegin;
9881c3436cfSJed Brown   if (order == tab->order) {
989108c343cSJed Brown     if (ros->status == TS_STEP_INCOMPLETE) { /* Use standard completion formula */
9909566063dSJacob Faibussowitsch       PetscCall(VecCopy(ts->vec_sol, U));
991de19f811SJed Brown       for (i = 0; i < tab->s; i++) w[i] = tab->bt[i];
9929566063dSJacob Faibussowitsch       PetscCall(VecMAXPY(U, tab->s, w, ros->Y));
9939566063dSJacob Faibussowitsch     } else PetscCall(VecCopy(ts->vec_sol, U));
9941c3436cfSJed Brown     if (done) *done = PETSC_TRUE;
9953ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
9961c3436cfSJed Brown   } else if (order == tab->order - 1) {
9971c3436cfSJed Brown     if (!tab->bembedt) goto unavailable;
998108c343cSJed Brown     if (ros->status == TS_STEP_INCOMPLETE) { /* Use embedded completion formula */
9999566063dSJacob Faibussowitsch       PetscCall(VecCopy(ts->vec_sol, U));
1000de19f811SJed Brown       for (i = 0; i < tab->s; i++) w[i] = tab->bembedt[i];
10019566063dSJacob Faibussowitsch       PetscCall(VecMAXPY(U, tab->s, w, ros->Y));
1002108c343cSJed Brown     } else { /* Use rollback-and-recomplete formula (bembedt - bt) */
1003108c343cSJed Brown       for (i = 0; i < tab->s; i++) w[i] = tab->bembedt[i] - tab->bt[i];
10049566063dSJacob Faibussowitsch       PetscCall(VecCopy(ts->vec_sol, U));
10059566063dSJacob Faibussowitsch       PetscCall(VecMAXPY(U, tab->s, w, ros->Y));
10061c3436cfSJed Brown     }
10071c3436cfSJed Brown     if (done) *done = PETSC_TRUE;
10083ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
10091c3436cfSJed Brown   }
10101c3436cfSJed Brown unavailable:
10111c3436cfSJed Brown   if (done) *done = PETSC_FALSE;
10129371c9d4SSatish Balay   else
10139371c9d4SSatish Balay     SETERRQ(PetscObjectComm((PetscObject)ts), PETSC_ERR_SUP, "Rosenbrock-W '%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,
10149371c9d4SSatish Balay             tab->order, order);
10153ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10161c3436cfSJed Brown }
10171c3436cfSJed Brown 
1018d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSStep_RosW(TS ts)
1019d71ae5a4SJacob Faibussowitsch {
102061692a83SJed Brown   TS_RosW         *ros = (TS_RosW *)ts->data;
102161692a83SJed Brown   RosWTableau      tab = ros->tableau;
1022e27a552bSJed Brown   const PetscInt   s   = tab->s;
10231c3436cfSJed Brown   const PetscReal *At = tab->At, *Gamma = tab->Gamma, *ASum = tab->ASum, *GammaInv = tab->GammaInv;
10240feba352SEmil Constantinescu   const PetscReal *GammaExplicitCorr = tab->GammaExplicitCorr;
1025c17803e7SJed Brown   const PetscBool *GammaZeroDiag     = tab->GammaZeroDiag;
102661692a83SJed Brown   PetscScalar     *w                 = ros->work;
10277d4bf2deSEmil Constantinescu   Vec             *Y = ros->Y, Ydot = ros->Ydot, Zdot = ros->Zdot, Zstage = ros->Zstage;
1028e27a552bSJed Brown   SNES             snes;
10291c3436cfSJed Brown   TSAdapt          adapt;
1030fecfb714SLisandro Dalcin   PetscInt         i, j, its, lits;
1031be5899b3SLisandro Dalcin   PetscInt         rejections = 0;
1032b39943a6SLisandro Dalcin   PetscBool        stageok, accept = PETSC_TRUE;
1033b39943a6SLisandro Dalcin   PetscReal        next_time_step = ts->time_step;
1034f7f07198SBarry Smith   PetscInt         lag;
1035e27a552bSJed Brown 
1036e27a552bSJed Brown   PetscFunctionBegin;
103748a46eb9SPierre Jolivet   if (!ts->steprollback) PetscCall(VecCopy(ts->vec_sol, ros->vec_sol_prev));
1038e27a552bSJed Brown 
1039b39943a6SLisandro Dalcin   ros->status = TS_STEP_INCOMPLETE;
1040b39943a6SLisandro Dalcin   while (!ts->reason && ros->status != TS_STEP_COMPLETE) {
10411c3436cfSJed Brown     const PetscReal h = ts->time_step;
1042e27a552bSJed Brown     for (i = 0; i < s; i++) {
10431c3436cfSJed Brown       ros->stage_time = ts->ptime + h * ASum[i];
10449566063dSJacob Faibussowitsch       PetscCall(TSPreStage(ts, ros->stage_time));
1045c17803e7SJed Brown       if (GammaZeroDiag[i]) {
1046c17803e7SJed Brown         ros->stage_explicit = PETSC_TRUE;
1047b296d7d5SJed Brown         ros->scoeff         = 1.;
1048c17803e7SJed Brown       } else {
1049c17803e7SJed Brown         ros->stage_explicit = PETSC_FALSE;
1050b296d7d5SJed Brown         ros->scoeff         = 1. / Gamma[i * s + i];
1051fd96d5b0SEmil Constantinescu       }
105261692a83SJed Brown 
10539566063dSJacob Faibussowitsch       PetscCall(VecCopy(ts->vec_sol, Zstage));
1054de19f811SJed Brown       for (j = 0; j < i; j++) w[j] = At[i * s + j];
10559566063dSJacob Faibussowitsch       PetscCall(VecMAXPY(Zstage, i, w, Y));
105661692a83SJed Brown 
105761692a83SJed Brown       for (j = 0; j < i; j++) w[j] = 1. / h * GammaInv[i * s + j];
10589566063dSJacob Faibussowitsch       PetscCall(VecZeroEntries(Zdot));
10599566063dSJacob Faibussowitsch       PetscCall(VecMAXPY(Zdot, i, w, Y));
106061692a83SJed Brown 
1061e27a552bSJed Brown       /* Initial guess taken from last stage */
10629566063dSJacob Faibussowitsch       PetscCall(VecZeroEntries(Y[i]));
106361692a83SJed Brown 
10647d4bf2deSEmil Constantinescu       if (!ros->stage_explicit) {
10659566063dSJacob Faibussowitsch         PetscCall(TSGetSNES(ts, &snes));
106661692a83SJed Brown         if (!ros->recompute_jacobian && !i) {
10679566063dSJacob Faibussowitsch           PetscCall(SNESGetLagJacobian(snes, &lag));
10686aad120cSJose E. Roman           if (lag == 1) {                            /* use did not set a nontrivial lag, so lag over all stages */
10699566063dSJacob Faibussowitsch             PetscCall(SNESSetLagJacobian(snes, -2)); /* Recompute the Jacobian on this solve, but not again for the rest of the stages */
1070f7f07198SBarry Smith           }
107161692a83SJed Brown         }
10729566063dSJacob Faibussowitsch         PetscCall(SNESSolve(snes, NULL, Y[i]));
10739371c9d4SSatish Balay         if (!ros->recompute_jacobian && i == s - 1 && lag == 1) { PetscCall(SNESSetLagJacobian(snes, lag)); /* Set lag back to 1 so we know user did not set it */ }
10749566063dSJacob Faibussowitsch         PetscCall(SNESGetIterationNumber(snes, &its));
10759566063dSJacob Faibussowitsch         PetscCall(SNESGetLinearSolveIterations(snes, &lits));
10769371c9d4SSatish Balay         ts->snes_its += its;
10779371c9d4SSatish Balay         ts->ksp_its += lits;
10787d4bf2deSEmil Constantinescu       } else {
10791ce71dffSSatish Balay         Mat J, Jp;
10809566063dSJacob Faibussowitsch         PetscCall(VecZeroEntries(Ydot)); /* Evaluate Y[i]=G(t,Ydot=0,Zstage) */
10819566063dSJacob Faibussowitsch         PetscCall(TSComputeIFunction(ts, ros->stage_time, Zstage, Ydot, Y[i], PETSC_FALSE));
10829566063dSJacob Faibussowitsch         PetscCall(VecScale(Y[i], -1.0));
10839566063dSJacob Faibussowitsch         PetscCall(VecAXPY(Y[i], -1.0, Zdot)); /*Y[i] = F(Zstage)-Zdot[=GammaInv*Y]*/
10840feba352SEmil Constantinescu 
10859566063dSJacob Faibussowitsch         PetscCall(VecZeroEntries(Zstage)); /* Zstage = GammaExplicitCorr[i,j] * Y[j] */
10860feba352SEmil Constantinescu         for (j = 0; j < i; j++) w[j] = GammaExplicitCorr[i * s + j];
10879566063dSJacob Faibussowitsch         PetscCall(VecMAXPY(Zstage, i, w, Y));
1088fecfb714SLisandro Dalcin 
1089fecfb714SLisandro Dalcin         /* Y[i] = Y[i] + Jac*Zstage[=Jac*GammaExplicitCorr[i,j] * Y[j]] */
10909566063dSJacob Faibussowitsch         PetscCall(TSGetIJacobian(ts, &J, &Jp, NULL, NULL));
10919566063dSJacob Faibussowitsch         PetscCall(TSComputeIJacobian(ts, ros->stage_time, ts->vec_sol, Ydot, 0, J, Jp, PETSC_FALSE));
10929566063dSJacob Faibussowitsch         PetscCall(MatMult(J, Zstage, Zdot));
10939566063dSJacob Faibussowitsch         PetscCall(VecAXPY(Y[i], -1.0, Zdot));
10945ef26d82SJed Brown         ts->ksp_its += 1;
1095fecfb714SLisandro Dalcin 
10969566063dSJacob Faibussowitsch         PetscCall(VecScale(Y[i], h));
10977d4bf2deSEmil Constantinescu       }
10989566063dSJacob Faibussowitsch       PetscCall(TSPostStage(ts, ros->stage_time, i, Y));
10999566063dSJacob Faibussowitsch       PetscCall(TSGetAdapt(ts, &adapt));
11009566063dSJacob Faibussowitsch       PetscCall(TSAdaptCheckStage(adapt, ts, ros->stage_time, Y[i], &stageok));
1101fecfb714SLisandro Dalcin       if (!stageok) goto reject_step;
1102e27a552bSJed Brown     }
1103e27a552bSJed Brown 
1104b39943a6SLisandro Dalcin     ros->status = TS_STEP_INCOMPLETE;
11059566063dSJacob Faibussowitsch     PetscCall(TSEvaluateStep_RosW(ts, tab->order, ts->vec_sol, NULL));
1106b39943a6SLisandro Dalcin     ros->status = TS_STEP_PENDING;
11079566063dSJacob Faibussowitsch     PetscCall(TSGetAdapt(ts, &adapt));
11089566063dSJacob Faibussowitsch     PetscCall(TSAdaptCandidatesClear(adapt));
11099566063dSJacob Faibussowitsch     PetscCall(TSAdaptCandidateAdd(adapt, tab->name, tab->order, 1, tab->ccfl, (PetscReal)tab->s, PETSC_TRUE));
11109566063dSJacob Faibussowitsch     PetscCall(TSAdaptChoose(adapt, ts, ts->time_step, NULL, &next_time_step, &accept));
1111b39943a6SLisandro Dalcin     ros->status = accept ? TS_STEP_COMPLETE : TS_STEP_INCOMPLETE;
1112b39943a6SLisandro Dalcin     if (!accept) { /* Roll back the current step */
1113c61711c8SStefano Zampini       PetscCall(VecCopy(ts->vec_sol0, ts->vec_sol));
1114be5899b3SLisandro Dalcin       ts->time_step = next_time_step;
1115be5899b3SLisandro Dalcin       goto reject_step;
1116b39943a6SLisandro Dalcin     }
1117b39943a6SLisandro Dalcin 
1118e27a552bSJed Brown     ts->ptime += ts->time_step;
1119cdbf8f93SLisandro Dalcin     ts->time_step = next_time_step;
11201c3436cfSJed Brown     break;
1121b39943a6SLisandro Dalcin 
1122b39943a6SLisandro Dalcin   reject_step:
11239371c9d4SSatish Balay     ts->reject++;
11249371c9d4SSatish Balay     accept = PETSC_FALSE;
1125be5899b3SLisandro Dalcin     if (!ts->reason && ++rejections > ts->max_reject && ts->max_reject >= 0) {
1126b39943a6SLisandro Dalcin       ts->reason = TS_DIVERGED_STEP_REJECTED;
112763a3b9bcSJacob Faibussowitsch       PetscCall(PetscInfo(ts, "Step=%" PetscInt_FMT ", step rejections %" PetscInt_FMT " greater than current TS allowed, stopping solve\n", ts->steps, rejections));
11281c3436cfSJed Brown     }
11291c3436cfSJed Brown   }
11303ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1131e27a552bSJed Brown }
1132e27a552bSJed Brown 
1133d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSInterpolate_RosW(TS ts, PetscReal itime, Vec U)
1134d71ae5a4SJacob Faibussowitsch {
113561692a83SJed Brown   TS_RosW         *ros = (TS_RosW *)ts->data;
1136f4aed992SEmil Constantinescu   PetscInt         s = ros->tableau->s, pinterp = ros->tableau->pinterp, i, j;
1137f4aed992SEmil Constantinescu   PetscReal        h;
1138f4aed992SEmil Constantinescu   PetscReal        tt, t;
1139f4aed992SEmil Constantinescu   PetscScalar     *bt;
1140f4aed992SEmil Constantinescu   const PetscReal *Bt       = ros->tableau->binterpt;
1141f4aed992SEmil Constantinescu   const PetscReal *GammaInv = ros->tableau->GammaInv;
1142f4aed992SEmil Constantinescu   PetscScalar     *w        = ros->work;
1143f4aed992SEmil Constantinescu   Vec             *Y        = ros->Y;
1144e27a552bSJed Brown 
1145e27a552bSJed Brown   PetscFunctionBegin;
11463c633725SBarry Smith   PetscCheck(Bt, PetscObjectComm((PetscObject)ts), PETSC_ERR_SUP, "TSRosW %s does not have an interpolation formula", ros->tableau->name);
1147f4aed992SEmil Constantinescu 
1148f4aed992SEmil Constantinescu   switch (ros->status) {
1149f4aed992SEmil Constantinescu   case TS_STEP_INCOMPLETE:
1150f4aed992SEmil Constantinescu   case TS_STEP_PENDING:
1151f4aed992SEmil Constantinescu     h = ts->time_step;
1152f4aed992SEmil Constantinescu     t = (itime - ts->ptime) / h;
1153f4aed992SEmil Constantinescu     break;
1154f4aed992SEmil Constantinescu   case TS_STEP_COMPLETE:
1155be5899b3SLisandro Dalcin     h = ts->ptime - ts->ptime_prev;
1156f4aed992SEmil Constantinescu     t = (itime - ts->ptime) / h + 1; /* In the interval [0,1] */
1157f4aed992SEmil Constantinescu     break;
1158d71ae5a4SJacob Faibussowitsch   default:
1159d71ae5a4SJacob Faibussowitsch     SETERRQ(PetscObjectComm((PetscObject)ts), PETSC_ERR_PLIB, "Invalid TSStepStatus");
1160f4aed992SEmil Constantinescu   }
11619566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(s, &bt));
1162f4aed992SEmil Constantinescu   for (i = 0; i < s; i++) bt[i] = 0;
1163f4aed992SEmil Constantinescu   for (j = 0, tt = t; j < pinterp; j++, tt *= t) {
1164ad540459SPierre Jolivet     for (i = 0; i < s; i++) bt[i] += Bt[i * pinterp + j] * tt;
1165f4aed992SEmil Constantinescu   }
1166f4aed992SEmil Constantinescu 
1167f4aed992SEmil Constantinescu   /* y(t+tt*h) = y(t) + Sum bt(tt) * GammaInv * Ydot */
1168f9c1d6abSBarry Smith   /* U <- 0*/
11699566063dSJacob Faibussowitsch   PetscCall(VecZeroEntries(U));
1170f9c1d6abSBarry Smith   /* U <- Sum bt_i * GammaInv(i,1:i) * Y(1:i) */
11713ca35412SEmil Constantinescu   for (j = 0; j < s; j++) w[j] = 0;
11723ca35412SEmil Constantinescu   for (j = 0; j < s; j++) {
1173ad540459SPierre Jolivet     for (i = j; i < s; i++) w[j] += bt[i] * GammaInv[i * s + j];
11743ca35412SEmil Constantinescu   }
11759566063dSJacob Faibussowitsch   PetscCall(VecMAXPY(U, i, w, Y));
1176be5899b3SLisandro Dalcin   /* U <- y(t) + U */
11779566063dSJacob Faibussowitsch   PetscCall(VecAXPY(U, 1, ros->vec_sol_prev));
1178f4aed992SEmil Constantinescu 
11799566063dSJacob Faibussowitsch   PetscCall(PetscFree(bt));
11803ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1181e27a552bSJed Brown }
1182e27a552bSJed Brown 
1183e27a552bSJed Brown /*------------------------------------------------------------*/
1184b39943a6SLisandro Dalcin 
1185d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSRosWTableauReset(TS ts)
1186d71ae5a4SJacob Faibussowitsch {
1187b39943a6SLisandro Dalcin   TS_RosW    *ros = (TS_RosW *)ts->data;
1188b39943a6SLisandro Dalcin   RosWTableau tab = ros->tableau;
1189b39943a6SLisandro Dalcin 
1190b39943a6SLisandro Dalcin   PetscFunctionBegin;
11913ba16761SJacob Faibussowitsch   if (!tab) PetscFunctionReturn(PETSC_SUCCESS);
11929566063dSJacob Faibussowitsch   PetscCall(VecDestroyVecs(tab->s, &ros->Y));
11939566063dSJacob Faibussowitsch   PetscCall(PetscFree(ros->work));
11943ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1195b39943a6SLisandro Dalcin }
1196b39943a6SLisandro Dalcin 
1197d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSReset_RosW(TS ts)
1198d71ae5a4SJacob Faibussowitsch {
119961692a83SJed Brown   TS_RosW *ros = (TS_RosW *)ts->data;
1200e27a552bSJed Brown 
1201e27a552bSJed Brown   PetscFunctionBegin;
12029566063dSJacob Faibussowitsch   PetscCall(TSRosWTableauReset(ts));
12039566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&ros->Ydot));
12049566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&ros->Ystage));
12059566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&ros->Zdot));
12069566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&ros->Zstage));
12079566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&ros->vec_sol_prev));
12083ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1209e27a552bSJed Brown }
1210e27a552bSJed Brown 
1211d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSRosWGetVecs(TS ts, DM dm, Vec *Ydot, Vec *Zdot, Vec *Ystage, Vec *Zstage)
1212d71ae5a4SJacob Faibussowitsch {
1213d5e6173cSPeter Brune   TS_RosW *rw = (TS_RosW *)ts->data;
1214d5e6173cSPeter Brune 
1215d5e6173cSPeter Brune   PetscFunctionBegin;
1216d5e6173cSPeter Brune   if (Ydot) {
1217d5e6173cSPeter Brune     if (dm && dm != ts->dm) {
12189566063dSJacob Faibussowitsch       PetscCall(DMGetNamedGlobalVector(dm, "TSRosW_Ydot", Ydot));
1219d5e6173cSPeter Brune     } else *Ydot = rw->Ydot;
1220d5e6173cSPeter Brune   }
1221d5e6173cSPeter Brune   if (Zdot) {
1222d5e6173cSPeter Brune     if (dm && dm != ts->dm) {
12239566063dSJacob Faibussowitsch       PetscCall(DMGetNamedGlobalVector(dm, "TSRosW_Zdot", Zdot));
1224d5e6173cSPeter Brune     } else *Zdot = rw->Zdot;
1225d5e6173cSPeter Brune   }
1226d5e6173cSPeter Brune   if (Ystage) {
1227d5e6173cSPeter Brune     if (dm && dm != ts->dm) {
12289566063dSJacob Faibussowitsch       PetscCall(DMGetNamedGlobalVector(dm, "TSRosW_Ystage", Ystage));
1229d5e6173cSPeter Brune     } else *Ystage = rw->Ystage;
1230d5e6173cSPeter Brune   }
1231d5e6173cSPeter Brune   if (Zstage) {
1232d5e6173cSPeter Brune     if (dm && dm != ts->dm) {
12339566063dSJacob Faibussowitsch       PetscCall(DMGetNamedGlobalVector(dm, "TSRosW_Zstage", Zstage));
1234d5e6173cSPeter Brune     } else *Zstage = rw->Zstage;
1235d5e6173cSPeter Brune   }
12363ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1237d5e6173cSPeter Brune }
1238d5e6173cSPeter Brune 
1239d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSRosWRestoreVecs(TS ts, DM dm, Vec *Ydot, Vec *Zdot, Vec *Ystage, Vec *Zstage)
1240d71ae5a4SJacob Faibussowitsch {
1241d5e6173cSPeter Brune   PetscFunctionBegin;
1242d5e6173cSPeter Brune   if (Ydot) {
124348a46eb9SPierre Jolivet     if (dm && dm != ts->dm) PetscCall(DMRestoreNamedGlobalVector(dm, "TSRosW_Ydot", Ydot));
1244d5e6173cSPeter Brune   }
1245d5e6173cSPeter Brune   if (Zdot) {
124648a46eb9SPierre Jolivet     if (dm && dm != ts->dm) PetscCall(DMRestoreNamedGlobalVector(dm, "TSRosW_Zdot", Zdot));
1247d5e6173cSPeter Brune   }
1248d5e6173cSPeter Brune   if (Ystage) {
124948a46eb9SPierre Jolivet     if (dm && dm != ts->dm) PetscCall(DMRestoreNamedGlobalVector(dm, "TSRosW_Ystage", Ystage));
1250d5e6173cSPeter Brune   }
1251d5e6173cSPeter Brune   if (Zstage) {
125248a46eb9SPierre Jolivet     if (dm && dm != ts->dm) PetscCall(DMRestoreNamedGlobalVector(dm, "TSRosW_Zstage", Zstage));
1253d5e6173cSPeter Brune   }
12543ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1255d5e6173cSPeter Brune }
1256d5e6173cSPeter Brune 
1257d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMCoarsenHook_TSRosW(DM fine, DM coarse, void *ctx)
1258d71ae5a4SJacob Faibussowitsch {
1259d5e6173cSPeter Brune   PetscFunctionBegin;
12603ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1261d5e6173cSPeter Brune }
1262d5e6173cSPeter Brune 
1263d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMRestrictHook_TSRosW(DM fine, Mat restrct, Vec rscale, Mat inject, DM coarse, void *ctx)
1264d71ae5a4SJacob Faibussowitsch {
1265d5e6173cSPeter Brune   TS  ts = (TS)ctx;
1266d5e6173cSPeter Brune   Vec Ydot, Zdot, Ystage, Zstage;
1267d5e6173cSPeter Brune   Vec Ydotc, Zdotc, Ystagec, Zstagec;
1268d5e6173cSPeter Brune 
1269d5e6173cSPeter Brune   PetscFunctionBegin;
12709566063dSJacob Faibussowitsch   PetscCall(TSRosWGetVecs(ts, fine, &Ydot, &Ystage, &Zdot, &Zstage));
12719566063dSJacob Faibussowitsch   PetscCall(TSRosWGetVecs(ts, coarse, &Ydotc, &Ystagec, &Zdotc, &Zstagec));
12729566063dSJacob Faibussowitsch   PetscCall(MatRestrict(restrct, Ydot, Ydotc));
12739566063dSJacob Faibussowitsch   PetscCall(VecPointwiseMult(Ydotc, rscale, Ydotc));
12749566063dSJacob Faibussowitsch   PetscCall(MatRestrict(restrct, Ystage, Ystagec));
12759566063dSJacob Faibussowitsch   PetscCall(VecPointwiseMult(Ystagec, rscale, Ystagec));
12769566063dSJacob Faibussowitsch   PetscCall(MatRestrict(restrct, Zdot, Zdotc));
12779566063dSJacob Faibussowitsch   PetscCall(VecPointwiseMult(Zdotc, rscale, Zdotc));
12789566063dSJacob Faibussowitsch   PetscCall(MatRestrict(restrct, Zstage, Zstagec));
12799566063dSJacob Faibussowitsch   PetscCall(VecPointwiseMult(Zstagec, rscale, Zstagec));
12809566063dSJacob Faibussowitsch   PetscCall(TSRosWRestoreVecs(ts, fine, &Ydot, &Ystage, &Zdot, &Zstage));
12819566063dSJacob Faibussowitsch   PetscCall(TSRosWRestoreVecs(ts, coarse, &Ydotc, &Ystagec, &Zdotc, &Zstagec));
12823ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1283d5e6173cSPeter Brune }
1284d5e6173cSPeter Brune 
1285d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMSubDomainHook_TSRosW(DM fine, DM coarse, void *ctx)
1286d71ae5a4SJacob Faibussowitsch {
1287258e1594SPeter Brune   PetscFunctionBegin;
12883ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1289258e1594SPeter Brune }
1290258e1594SPeter Brune 
1291d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMSubDomainRestrictHook_TSRosW(DM dm, VecScatter gscat, VecScatter lscat, DM subdm, void *ctx)
1292d71ae5a4SJacob Faibussowitsch {
1293258e1594SPeter Brune   TS  ts = (TS)ctx;
1294258e1594SPeter Brune   Vec Ydot, Zdot, Ystage, Zstage;
1295258e1594SPeter Brune   Vec Ydots, Zdots, Ystages, Zstages;
1296258e1594SPeter Brune 
1297258e1594SPeter Brune   PetscFunctionBegin;
12989566063dSJacob Faibussowitsch   PetscCall(TSRosWGetVecs(ts, dm, &Ydot, &Ystage, &Zdot, &Zstage));
12999566063dSJacob Faibussowitsch   PetscCall(TSRosWGetVecs(ts, subdm, &Ydots, &Ystages, &Zdots, &Zstages));
1300258e1594SPeter Brune 
13019566063dSJacob Faibussowitsch   PetscCall(VecScatterBegin(gscat, Ydot, Ydots, INSERT_VALUES, SCATTER_FORWARD));
13029566063dSJacob Faibussowitsch   PetscCall(VecScatterEnd(gscat, Ydot, Ydots, INSERT_VALUES, SCATTER_FORWARD));
1303258e1594SPeter Brune 
13049566063dSJacob Faibussowitsch   PetscCall(VecScatterBegin(gscat, Ystage, Ystages, INSERT_VALUES, SCATTER_FORWARD));
13059566063dSJacob Faibussowitsch   PetscCall(VecScatterEnd(gscat, Ystage, Ystages, INSERT_VALUES, SCATTER_FORWARD));
1306258e1594SPeter Brune 
13079566063dSJacob Faibussowitsch   PetscCall(VecScatterBegin(gscat, Zdot, Zdots, INSERT_VALUES, SCATTER_FORWARD));
13089566063dSJacob Faibussowitsch   PetscCall(VecScatterEnd(gscat, Zdot, Zdots, INSERT_VALUES, SCATTER_FORWARD));
1309258e1594SPeter Brune 
13109566063dSJacob Faibussowitsch   PetscCall(VecScatterBegin(gscat, Zstage, Zstages, INSERT_VALUES, SCATTER_FORWARD));
13119566063dSJacob Faibussowitsch   PetscCall(VecScatterEnd(gscat, Zstage, Zstages, INSERT_VALUES, SCATTER_FORWARD));
1312258e1594SPeter Brune 
13139566063dSJacob Faibussowitsch   PetscCall(TSRosWRestoreVecs(ts, dm, &Ydot, &Ystage, &Zdot, &Zstage));
13149566063dSJacob Faibussowitsch   PetscCall(TSRosWRestoreVecs(ts, subdm, &Ydots, &Ystages, &Zdots, &Zstages));
13153ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1316258e1594SPeter Brune }
1317258e1594SPeter Brune 
1318d71ae5a4SJacob Faibussowitsch static PetscErrorCode SNESTSFormFunction_RosW(SNES snes, Vec U, Vec F, TS ts)
1319d71ae5a4SJacob Faibussowitsch {
132061692a83SJed Brown   TS_RosW  *ros = (TS_RosW *)ts->data;
1321d5e6173cSPeter Brune   Vec       Ydot, Zdot, Ystage, Zstage;
1322b296d7d5SJed Brown   PetscReal shift = ros->scoeff / ts->time_step;
1323d5e6173cSPeter Brune   DM        dm, dmsave;
1324e27a552bSJed Brown 
1325e27a552bSJed Brown   PetscFunctionBegin;
13269566063dSJacob Faibussowitsch   PetscCall(SNESGetDM(snes, &dm));
13279566063dSJacob Faibussowitsch   PetscCall(TSRosWGetVecs(ts, dm, &Ydot, &Zdot, &Ystage, &Zstage));
13289566063dSJacob Faibussowitsch   PetscCall(VecWAXPY(Ydot, shift, U, Zdot));   /* Ydot = shift*U + Zdot */
13299566063dSJacob Faibussowitsch   PetscCall(VecWAXPY(Ystage, 1.0, U, Zstage)); /* Ystage = U + Zstage */
1330d5e6173cSPeter Brune   dmsave = ts->dm;
1331d5e6173cSPeter Brune   ts->dm = dm;
13329566063dSJacob Faibussowitsch   PetscCall(TSComputeIFunction(ts, ros->stage_time, Ystage, Ydot, F, PETSC_FALSE));
1333d5e6173cSPeter Brune   ts->dm = dmsave;
13349566063dSJacob Faibussowitsch   PetscCall(TSRosWRestoreVecs(ts, dm, &Ydot, &Zdot, &Ystage, &Zstage));
13353ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1336e27a552bSJed Brown }
1337e27a552bSJed Brown 
1338d71ae5a4SJacob Faibussowitsch static PetscErrorCode SNESTSFormJacobian_RosW(SNES snes, Vec U, Mat A, Mat B, TS ts)
1339d71ae5a4SJacob Faibussowitsch {
134061692a83SJed Brown   TS_RosW  *ros = (TS_RosW *)ts->data;
1341d5e6173cSPeter Brune   Vec       Ydot, Zdot, Ystage, Zstage;
1342b296d7d5SJed Brown   PetscReal shift = ros->scoeff / ts->time_step;
1343d5e6173cSPeter Brune   DM        dm, dmsave;
1344e27a552bSJed Brown 
1345e27a552bSJed Brown   PetscFunctionBegin;
134661692a83SJed Brown   /* ros->Ydot and ros->Ystage have already been computed in SNESTSFormFunction_RosW (SNES guarantees this) */
13479566063dSJacob Faibussowitsch   PetscCall(SNESGetDM(snes, &dm));
13489566063dSJacob Faibussowitsch   PetscCall(TSRosWGetVecs(ts, dm, &Ydot, &Zdot, &Ystage, &Zstage));
1349d5e6173cSPeter Brune   dmsave = ts->dm;
1350d5e6173cSPeter Brune   ts->dm = dm;
13519566063dSJacob Faibussowitsch   PetscCall(TSComputeIJacobian(ts, ros->stage_time, Ystage, Ydot, shift, A, B, PETSC_TRUE));
1352d5e6173cSPeter Brune   ts->dm = dmsave;
13539566063dSJacob Faibussowitsch   PetscCall(TSRosWRestoreVecs(ts, dm, &Ydot, &Zdot, &Ystage, &Zstage));
13543ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1355e27a552bSJed Brown }
1356e27a552bSJed Brown 
1357d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSRosWTableauSetUp(TS ts)
1358d71ae5a4SJacob Faibussowitsch {
1359b39943a6SLisandro Dalcin   TS_RosW    *ros = (TS_RosW *)ts->data;
1360b39943a6SLisandro Dalcin   RosWTableau tab = ros->tableau;
1361b39943a6SLisandro Dalcin 
1362b39943a6SLisandro Dalcin   PetscFunctionBegin;
13639566063dSJacob Faibussowitsch   PetscCall(VecDuplicateVecs(ts->vec_sol, tab->s, &ros->Y));
13649566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(tab->s, &ros->work));
13653ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1366b39943a6SLisandro Dalcin }
1367b39943a6SLisandro Dalcin 
1368d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSSetUp_RosW(TS ts)
1369d71ae5a4SJacob Faibussowitsch {
137061692a83SJed Brown   TS_RosW         *ros = (TS_RosW *)ts->data;
1371d5e6173cSPeter Brune   DM               dm;
1372b39943a6SLisandro Dalcin   SNES             snes;
13738434afd1SBarry Smith   TSRHSJacobianFn *rhsjacobian;
1374e27a552bSJed Brown 
1375e27a552bSJed Brown   PetscFunctionBegin;
13769566063dSJacob Faibussowitsch   PetscCall(TSRosWTableauSetUp(ts));
13779566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(ts->vec_sol, &ros->Ydot));
13789566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(ts->vec_sol, &ros->Ystage));
13799566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(ts->vec_sol, &ros->Zdot));
13809566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(ts->vec_sol, &ros->Zstage));
13819566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(ts->vec_sol, &ros->vec_sol_prev));
13829566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
13839566063dSJacob Faibussowitsch   PetscCall(DMCoarsenHookAdd(dm, DMCoarsenHook_TSRosW, DMRestrictHook_TSRosW, ts));
13849566063dSJacob Faibussowitsch   PetscCall(DMSubDomainHookAdd(dm, DMSubDomainHook_TSRosW, DMSubDomainRestrictHook_TSRosW, ts));
1385b39943a6SLisandro Dalcin   /* Rosenbrock methods are linearly implicit, so set that unless the user has specifically asked for something else */
13869566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts, &snes));
138748a46eb9SPierre Jolivet   if (!((PetscObject)snes)->type_name) PetscCall(SNESSetType(snes, SNESKSPONLY));
13889566063dSJacob Faibussowitsch   PetscCall(DMTSGetRHSJacobian(dm, &rhsjacobian, NULL));
1389a3ab5968SHong Zhang   if (rhsjacobian == TSComputeRHSJacobianConstant) {
1390a3ab5968SHong Zhang     Mat Amat, Pmat;
1391a3ab5968SHong Zhang 
1392a3ab5968SHong Zhang     /* Set the SNES matrix to be different from the RHS matrix because there is no way to reconstruct shift*M-J */
13939566063dSJacob Faibussowitsch     PetscCall(SNESGetJacobian(snes, &Amat, &Pmat, NULL, NULL));
1394a3ab5968SHong Zhang     if (Amat && Amat == ts->Arhs) {
1395a3ab5968SHong Zhang       if (Amat == Pmat) {
13969566063dSJacob Faibussowitsch         PetscCall(MatDuplicate(ts->Arhs, MAT_COPY_VALUES, &Amat));
13979566063dSJacob Faibussowitsch         PetscCall(SNESSetJacobian(snes, Amat, Amat, NULL, NULL));
1398a3ab5968SHong Zhang       } else {
13999566063dSJacob Faibussowitsch         PetscCall(MatDuplicate(ts->Arhs, MAT_COPY_VALUES, &Amat));
14009566063dSJacob Faibussowitsch         PetscCall(SNESSetJacobian(snes, Amat, NULL, NULL, NULL));
1401a3ab5968SHong Zhang         if (Pmat && Pmat == ts->Brhs) {
14029566063dSJacob Faibussowitsch           PetscCall(MatDuplicate(ts->Brhs, MAT_COPY_VALUES, &Pmat));
14039566063dSJacob Faibussowitsch           PetscCall(SNESSetJacobian(snes, NULL, Pmat, NULL, NULL));
14049566063dSJacob Faibussowitsch           PetscCall(MatDestroy(&Pmat));
1405a3ab5968SHong Zhang         }
1406a3ab5968SHong Zhang       }
14079566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&Amat));
1408a3ab5968SHong Zhang     }
1409a3ab5968SHong Zhang   }
14103ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1411e27a552bSJed Brown }
1412e27a552bSJed Brown /*------------------------------------------------------------*/
1413e27a552bSJed Brown 
1414d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSSetFromOptions_RosW(TS ts, PetscOptionItems *PetscOptionsObject)
1415d71ae5a4SJacob Faibussowitsch {
141661692a83SJed Brown   TS_RosW *ros = (TS_RosW *)ts->data;
1417b39943a6SLisandro Dalcin   SNES     snes;
1418e27a552bSJed Brown 
1419e27a552bSJed Brown   PetscFunctionBegin;
1420d0609cedSBarry Smith   PetscOptionsHeadBegin(PetscOptionsObject, "RosW ODE solver options");
1421e27a552bSJed Brown   {
142261692a83SJed Brown     RosWTableauLink link;
1423e27a552bSJed Brown     PetscInt        count, choice;
1424e27a552bSJed Brown     PetscBool       flg;
1425e27a552bSJed Brown     const char    **namelist;
142661692a83SJed Brown 
1427fbccb6d4SPierre Jolivet     for (link = RosWTableauList, count = 0; link; link = link->next, count++);
14289566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(count, (char ***)&namelist));
142961692a83SJed Brown     for (link = RosWTableauList, count = 0; link; link = link->next, count++) namelist[count] = link->tab.name;
14309566063dSJacob Faibussowitsch     PetscCall(PetscOptionsEList("-ts_rosw_type", "Family of Rosenbrock-W method", "TSRosWSetType", (const char *const *)namelist, count, ros->tableau->name, &choice, &flg));
14319566063dSJacob Faibussowitsch     if (flg) PetscCall(TSRosWSetType(ts, namelist[choice]));
14329566063dSJacob Faibussowitsch     PetscCall(PetscFree(namelist));
143361692a83SJed Brown 
14349566063dSJacob Faibussowitsch     PetscCall(PetscOptionsBool("-ts_rosw_recompute_jacobian", "Recompute the Jacobian at each stage", "TSRosWSetRecomputeJacobian", ros->recompute_jacobian, &ros->recompute_jacobian, NULL));
1435b39943a6SLisandro Dalcin   }
1436d0609cedSBarry Smith   PetscOptionsHeadEnd();
143761692a83SJed Brown   /* Rosenbrock methods are linearly implicit, so set that unless the user has specifically asked for something else */
14389566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts, &snes));
143948a46eb9SPierre Jolivet   if (!((PetscObject)snes)->type_name) PetscCall(SNESSetType(snes, SNESKSPONLY));
14403ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1441e27a552bSJed Brown }
1442e27a552bSJed Brown 
1443d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSView_RosW(TS ts, PetscViewer viewer)
1444d71ae5a4SJacob Faibussowitsch {
144561692a83SJed Brown   TS_RosW  *ros = (TS_RosW *)ts->data;
1446e27a552bSJed Brown   PetscBool iascii;
1447e27a552bSJed Brown 
1448e27a552bSJed Brown   PetscFunctionBegin;
14499566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
1450e27a552bSJed Brown   if (iascii) {
14519c334d8fSLisandro Dalcin     RosWTableau tab = ros->tableau;
145219fd82e9SBarry Smith     TSRosWType  rostype;
14539c334d8fSLisandro Dalcin     char        buf[512];
1454e408995aSJed Brown     PetscInt    i;
1455e408995aSJed Brown     PetscReal   abscissa[512];
14569566063dSJacob Faibussowitsch     PetscCall(TSRosWGetType(ts, &rostype));
14579566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "  Rosenbrock-W %s\n", rostype));
14589566063dSJacob Faibussowitsch     PetscCall(PetscFormatRealArray(buf, sizeof(buf), "% 8.6f", tab->s, tab->ASum));
14599566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "  Abscissa of A       = %s\n", buf));
1460e408995aSJed Brown     for (i = 0; i < tab->s; i++) abscissa[i] = tab->ASum[i] + tab->Gamma[i];
14619566063dSJacob Faibussowitsch     PetscCall(PetscFormatRealArray(buf, sizeof(buf), "% 8.6f", tab->s, abscissa));
14629566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "  Abscissa of A+Gamma = %s\n", buf));
1463e27a552bSJed Brown   }
14643ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1465e27a552bSJed Brown }
1466e27a552bSJed Brown 
1467d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSLoad_RosW(TS ts, PetscViewer viewer)
1468d71ae5a4SJacob Faibussowitsch {
14699200755eSBarry Smith   SNES    snes;
14709c334d8fSLisandro Dalcin   TSAdapt adapt;
14719200755eSBarry Smith 
14729200755eSBarry Smith   PetscFunctionBegin;
14739566063dSJacob Faibussowitsch   PetscCall(TSGetAdapt(ts, &adapt));
14749566063dSJacob Faibussowitsch   PetscCall(TSAdaptLoad(adapt, viewer));
14759566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts, &snes));
14769566063dSJacob Faibussowitsch   PetscCall(SNESLoad(snes, viewer));
14779200755eSBarry Smith   /* function and Jacobian context for SNES when used with TS is always ts object */
14789566063dSJacob Faibussowitsch   PetscCall(SNESSetFunction(snes, NULL, NULL, ts));
14799566063dSJacob Faibussowitsch   PetscCall(SNESSetJacobian(snes, NULL, NULL, NULL, ts));
14803ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
14819200755eSBarry Smith }
14829200755eSBarry Smith 
1483e27a552bSJed Brown /*@C
1484bcf0153eSBarry Smith   TSRosWSetType - Set the type of Rosenbrock-W, `TSROSW`, scheme
1485e27a552bSJed Brown 
148620f4b53cSBarry Smith   Logically Collective
1487e27a552bSJed Brown 
1488d8d19677SJose E. Roman   Input Parameters:
1489e27a552bSJed Brown + ts       - timestepping context
1490b92453a8SLisandro Dalcin - roswtype - type of Rosenbrock-W scheme
1491e27a552bSJed Brown 
1492020d8f30SJed Brown   Level: beginner
1493e27a552bSJed Brown 
14941cc06b55SBarry Smith .seealso: [](ch_ts), `TSRosWGetType()`, `TSROSW`, `TSROSW2M`, `TSROSW2P`, `TSROSWRA3PW`, `TSROSWRA34PW2`, `TSROSWRODAS3`, `TSROSWSANDU3`, `TSROSWASSP3P3S1C`, `TSROSWLASSP3P4S2C`, `TSROSWLLSSP3P4S2C`, `TSROSWARK3`
1495e27a552bSJed Brown @*/
1496d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRosWSetType(TS ts, TSRosWType roswtype)
1497d71ae5a4SJacob Faibussowitsch {
1498e27a552bSJed Brown   PetscFunctionBegin;
1499e27a552bSJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
15004f572ea9SToby Isaac   PetscAssertPointer(roswtype, 2);
1501cac4c232SBarry Smith   PetscTryMethod(ts, "TSRosWSetType_C", (TS, TSRosWType), (ts, roswtype));
15023ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1503e27a552bSJed Brown }
1504e27a552bSJed Brown 
1505e27a552bSJed Brown /*@C
150661692a83SJed Brown   TSRosWGetType - Get the type of Rosenbrock-W scheme
1507e27a552bSJed Brown 
150820f4b53cSBarry Smith   Logically Collective
1509e27a552bSJed Brown 
1510e27a552bSJed Brown   Input Parameter:
1511e27a552bSJed Brown . ts - timestepping context
1512e27a552bSJed Brown 
1513e27a552bSJed Brown   Output Parameter:
151461692a83SJed Brown . rostype - type of Rosenbrock-W scheme
1515e27a552bSJed Brown 
1516e27a552bSJed Brown   Level: intermediate
1517e27a552bSJed Brown 
15181cc06b55SBarry Smith .seealso: [](ch_ts), `TSRosWType`, `TSRosWSetType()`
1519e27a552bSJed Brown @*/
1520d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRosWGetType(TS ts, TSRosWType *rostype)
1521d71ae5a4SJacob Faibussowitsch {
1522e27a552bSJed Brown   PetscFunctionBegin;
1523e27a552bSJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
1524cac4c232SBarry Smith   PetscUseMethod(ts, "TSRosWGetType_C", (TS, TSRosWType *), (ts, rostype));
15253ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1526e27a552bSJed Brown }
1527e27a552bSJed Brown 
1528e27a552bSJed Brown /*@C
152961692a83SJed Brown   TSRosWSetRecomputeJacobian - Set whether to recompute the Jacobian at each stage. The default is to update the Jacobian once per step.
1530e27a552bSJed Brown 
153120f4b53cSBarry Smith   Logically Collective
1532e27a552bSJed Brown 
1533d8d19677SJose E. Roman   Input Parameters:
1534e27a552bSJed Brown + ts  - timestepping context
1535bcf0153eSBarry Smith - flg - `PETSC_TRUE` to recompute the Jacobian at each stage
1536e27a552bSJed Brown 
1537e27a552bSJed Brown   Level: intermediate
1538e27a552bSJed Brown 
15391cc06b55SBarry Smith .seealso: [](ch_ts), `TSRosWType`, `TSRosWGetType()`
1540e27a552bSJed Brown @*/
1541d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRosWSetRecomputeJacobian(TS ts, PetscBool flg)
1542d71ae5a4SJacob Faibussowitsch {
1543e27a552bSJed Brown   PetscFunctionBegin;
1544e27a552bSJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
1545cac4c232SBarry Smith   PetscTryMethod(ts, "TSRosWSetRecomputeJacobian_C", (TS, PetscBool), (ts, flg));
15463ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1547e27a552bSJed Brown }
1548e27a552bSJed Brown 
1549d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSRosWGetType_RosW(TS ts, TSRosWType *rostype)
1550d71ae5a4SJacob Faibussowitsch {
155161692a83SJed Brown   TS_RosW *ros = (TS_RosW *)ts->data;
1552e27a552bSJed Brown 
1553e27a552bSJed Brown   PetscFunctionBegin;
155461692a83SJed Brown   *rostype = ros->tableau->name;
15553ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1556e27a552bSJed Brown }
1557ef20d060SBarry Smith 
1558d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSRosWSetType_RosW(TS ts, TSRosWType rostype)
1559d71ae5a4SJacob Faibussowitsch {
156061692a83SJed Brown   TS_RosW        *ros = (TS_RosW *)ts->data;
1561e27a552bSJed Brown   PetscBool       match;
156261692a83SJed Brown   RosWTableauLink link;
1563e27a552bSJed Brown 
1564e27a552bSJed Brown   PetscFunctionBegin;
156561692a83SJed Brown   if (ros->tableau) {
15669566063dSJacob Faibussowitsch     PetscCall(PetscStrcmp(ros->tableau->name, rostype, &match));
15673ba16761SJacob Faibussowitsch     if (match) PetscFunctionReturn(PETSC_SUCCESS);
1568e27a552bSJed Brown   }
156961692a83SJed Brown   for (link = RosWTableauList; link; link = link->next) {
15709566063dSJacob Faibussowitsch     PetscCall(PetscStrcmp(link->tab.name, rostype, &match));
1571e27a552bSJed Brown     if (match) {
15729566063dSJacob Faibussowitsch       if (ts->setupcalled) PetscCall(TSRosWTableauReset(ts));
157361692a83SJed Brown       ros->tableau = &link->tab;
15749566063dSJacob Faibussowitsch       if (ts->setupcalled) PetscCall(TSRosWTableauSetUp(ts));
15752ffb9264SLisandro Dalcin       ts->default_adapt_type = ros->tableau->bembed ? TSADAPTBASIC : TSADAPTNONE;
15763ba16761SJacob Faibussowitsch       PetscFunctionReturn(PETSC_SUCCESS);
1577e27a552bSJed Brown     }
1578e27a552bSJed Brown   }
157998921bdaSJacob Faibussowitsch   SETERRQ(PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_UNKNOWN_TYPE, "Could not find '%s'", rostype);
1580e27a552bSJed Brown }
158161692a83SJed Brown 
1582d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSRosWSetRecomputeJacobian_RosW(TS ts, PetscBool flg)
1583d71ae5a4SJacob Faibussowitsch {
158461692a83SJed Brown   TS_RosW *ros = (TS_RosW *)ts->data;
1585e27a552bSJed Brown 
1586e27a552bSJed Brown   PetscFunctionBegin;
158761692a83SJed Brown   ros->recompute_jacobian = flg;
15883ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1589e27a552bSJed Brown }
1590e27a552bSJed Brown 
1591d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSDestroy_RosW(TS ts)
1592d71ae5a4SJacob Faibussowitsch {
1593b3a6b972SJed Brown   PetscFunctionBegin;
15949566063dSJacob Faibussowitsch   PetscCall(TSReset_RosW(ts));
1595b3a6b972SJed Brown   if (ts->dm) {
15969566063dSJacob Faibussowitsch     PetscCall(DMCoarsenHookRemove(ts->dm, DMCoarsenHook_TSRosW, DMRestrictHook_TSRosW, ts));
15979566063dSJacob Faibussowitsch     PetscCall(DMSubDomainHookRemove(ts->dm, DMSubDomainHook_TSRosW, DMSubDomainRestrictHook_TSRosW, ts));
1598b3a6b972SJed Brown   }
15999566063dSJacob Faibussowitsch   PetscCall(PetscFree(ts->data));
16009566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSRosWGetType_C", NULL));
16019566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSRosWSetType_C", NULL));
16029566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSRosWSetRecomputeJacobian_C", NULL));
16033ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1604b3a6b972SJed Brown }
1605d5e6173cSPeter Brune 
1606e27a552bSJed Brown /* ------------------------------------------------------------ */
1607e27a552bSJed Brown /*MC
1608020d8f30SJed Brown       TSROSW - ODE solver using Rosenbrock-W schemes
1609e27a552bSJed Brown 
1610e27a552bSJed Brown   These methods are intended for problems with well-separated time scales, especially when a slow scale is strongly
1611e27a552bSJed Brown   nonlinear such that it is expensive to solve with a fully implicit method. The user should provide the stiff part
1612bcf0153eSBarry Smith   of the equation using `TSSetIFunction()` and the non-stiff part with `TSSetRHSFunction()`.
1613bcf0153eSBarry Smith 
1614bcf0153eSBarry Smith   Level: beginner
1615e27a552bSJed Brown 
1616e27a552bSJed Brown   Notes:
161761692a83SJed Brown   This method currently only works with autonomous ODE and DAE.
161861692a83SJed Brown 
1619bcf0153eSBarry Smith   Consider trying `TSARKIMEX` if the stiff part is strongly nonlinear.
1620d0685a90SJed Brown 
16213d5a8a6aSBarry Smith   Since this uses a single linear solve per time-step if you wish to lag the jacobian or preconditioner computation you must use also -snes_lag_jacobian_persists true or -snes_lag_jacobian_preconditioner true
16223d5a8a6aSBarry Smith 
1623e94cfbe0SPatrick Sanan   Developer Notes:
162461692a83SJed Brown   Rosenbrock-W methods are typically specified for autonomous ODE
162561692a83SJed Brown 
1626f9c1d6abSBarry Smith $  udot = f(u)
162761692a83SJed Brown 
162861692a83SJed Brown   by the stage equations
162961692a83SJed Brown 
1630f9c1d6abSBarry Smith $  k_i = h f(u_0 + sum_j alpha_ij k_j) + h J sum_j gamma_ij k_j
163161692a83SJed Brown 
163261692a83SJed Brown   and step completion formula
163361692a83SJed Brown 
1634f9c1d6abSBarry Smith $  u_1 = u_0 + sum_j b_j k_j
163561692a83SJed Brown 
1636f9c1d6abSBarry Smith   with step size h and coefficients alpha_ij, gamma_ij, and b_i. Implementing the method in this form would require f(u)
163761692a83SJed Brown   and the Jacobian J to be available, in addition to the shifted matrix I - h gamma_ii J. Following Hairer and Wanner,
163861692a83SJed Brown   we define new variables for the stage equations
163961692a83SJed Brown 
164061692a83SJed Brown $  y_i = gamma_ij k_j
164161692a83SJed Brown 
164261692a83SJed Brown   The k_j can be recovered because Gamma is invertible. Let C be the lower triangular part of Gamma^{-1} and define
164361692a83SJed Brown 
1644b70472e2SJed Brown $  A = Alpha Gamma^{-1}, bt^T = b^T Gamma^{-1}
164561692a83SJed Brown 
164661692a83SJed Brown   to rewrite the method as
164761692a83SJed Brown 
164837fdd005SBarry Smith .vb
164937fdd005SBarry Smith   [M/(h gamma_ii) - J] y_i = f(u_0 + sum_j a_ij y_j) + M sum_j (c_ij/h) y_j
165037fdd005SBarry Smith   u_1 = u_0 + sum_j bt_j y_j
165137fdd005SBarry Smith .ve
165261692a83SJed Brown 
165361692a83SJed Brown    where we have introduced the mass matrix M. Continue by defining
165461692a83SJed Brown 
165561692a83SJed Brown $  ydot_i = 1/(h gamma_ii) y_i - sum_j (c_ij/h) y_j
165661692a83SJed Brown 
165761692a83SJed Brown    or, more compactly in tensor notation
165861692a83SJed Brown 
165961692a83SJed Brown $  Ydot = 1/h (Gamma^{-1} \otimes I) Y .
166061692a83SJed Brown 
166161692a83SJed Brown    Note that Gamma^{-1} is lower triangular. With this definition of Ydot in terms of known quantities and the current
166261692a83SJed Brown    stage y_i, the stage equations reduce to performing one Newton step (typically with a lagged Jacobian) on the
166361692a83SJed Brown    equation
166461692a83SJed Brown 
1665f9c1d6abSBarry Smith $  g(u_0 + sum_j a_ij y_j + y_i, ydot_i) = 0
166661692a83SJed Brown 
166761692a83SJed Brown    with initial guess y_i = 0.
1668e27a552bSJed Brown 
16691cc06b55SBarry Smith .seealso: [](ch_ts), `TSCreate()`, `TS`, `TSSetType()`, `TSRosWSetType()`, `TSRosWRegister()`, `TSROSWTHETA1`, `TSROSWTHETA2`, `TSROSW2M`, `TSROSW2P`, `TSROSWRA3PW`, `TSROSWRA34PW2`, `TSROSWRODAS3`,
1670bcf0153eSBarry Smith           `TSROSWSANDU3`, `TSROSWASSP3P3S1C`, `TSROSWLASSP3P4S2C`, `TSROSWLLSSP3P4S2C`, `TSROSWGRK4T`, `TSROSWSHAMP4`, `TSROSWVELDD4`, `TSROSW4L`, `TSType`
1671e27a552bSJed Brown M*/
1672d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode TSCreate_RosW(TS ts)
1673d71ae5a4SJacob Faibussowitsch {
167461692a83SJed Brown   TS_RosW *ros;
1675e27a552bSJed Brown 
1676e27a552bSJed Brown   PetscFunctionBegin;
16779566063dSJacob Faibussowitsch   PetscCall(TSRosWInitializePackage());
1678e27a552bSJed Brown 
1679e27a552bSJed Brown   ts->ops->reset          = TSReset_RosW;
1680e27a552bSJed Brown   ts->ops->destroy        = TSDestroy_RosW;
1681e27a552bSJed Brown   ts->ops->view           = TSView_RosW;
16829200755eSBarry Smith   ts->ops->load           = TSLoad_RosW;
1683e27a552bSJed Brown   ts->ops->setup          = TSSetUp_RosW;
1684e27a552bSJed Brown   ts->ops->step           = TSStep_RosW;
1685e27a552bSJed Brown   ts->ops->interpolate    = TSInterpolate_RosW;
16861c3436cfSJed Brown   ts->ops->evaluatestep   = TSEvaluateStep_RosW;
1687e27a552bSJed Brown   ts->ops->setfromoptions = TSSetFromOptions_RosW;
1688e27a552bSJed Brown   ts->ops->snesfunction   = SNESTSFormFunction_RosW;
1689e27a552bSJed Brown   ts->ops->snesjacobian   = SNESTSFormJacobian_RosW;
1690e27a552bSJed Brown 
1691efd4aadfSBarry Smith   ts->usessnes = PETSC_TRUE;
1692efd4aadfSBarry Smith 
16934dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&ros));
169461692a83SJed Brown   ts->data = (void *)ros;
1695e27a552bSJed Brown 
16969566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSRosWGetType_C", TSRosWGetType_RosW));
16979566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSRosWSetType_C", TSRosWSetType_RosW));
16989566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSRosWSetRecomputeJacobian_C", TSRosWSetRecomputeJacobian_RosW));
1699b39943a6SLisandro Dalcin 
17009566063dSJacob Faibussowitsch   PetscCall(TSRosWSetType(ts, TSRosWDefault));
17013ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1702e27a552bSJed Brown }
1703