xref: /petsc/src/ts/impls/rosw/rosw.c (revision cac4c232dc4f93991e342196e27ef7b0655dac7b)
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 
733606a31eSEmil Constantinescu .seealso: 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 
833606a31eSEmil Constantinescu .seealso: 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 
93fe7e6d57SJed Brown .seealso: 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 
103fe7e6d57SJed Brown .seealso: TSROSW
104fe7e6d57SJed Brown M*/
105fe7e6d57SJed Brown 
106fe7e6d57SJed Brown /*MC
107fe7e6d57SJed Brown      TSROSWRA3PW - Three stage third order Rosenbrock-W scheme for PDAE of index 1.
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 
113fe7e6d57SJed Brown      References:
114606c0280SSatish Balay .  * - Rang and Angermann, New Rosenbrock W methods of order 3 for partial differential algebraic equations of index 1, 2005.
115fe7e6d57SJed Brown 
116fe7e6d57SJed Brown      Level: intermediate
117fe7e6d57SJed Brown 
118fe7e6d57SJed Brown .seealso: TSROSW
119fe7e6d57SJed Brown M*/
120fe7e6d57SJed Brown 
121fe7e6d57SJed Brown /*MC
122fe7e6d57SJed Brown      TSROSWRA34PW2 - Four stage third order L-stable Rosenbrock-W scheme for PDAE of index 1.
123fe7e6d57SJed Brown 
124fe7e6d57SJed Brown      Only an approximate Jacobian is needed. By default, it is only recomputed once per step.
125fe7e6d57SJed Brown 
126fe7e6d57SJed 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.
127fe7e6d57SJed Brown 
128fe7e6d57SJed Brown      References:
129606c0280SSatish Balay .  * - Rang and Angermann, New Rosenbrock W methods of order 3 for partial differential algebraic equations of index 1, 2005.
130fe7e6d57SJed Brown 
131fe7e6d57SJed Brown      Level: intermediate
132fe7e6d57SJed Brown 
133fe7e6d57SJed Brown .seealso: TSROSW
134fe7e6d57SJed Brown M*/
135fe7e6d57SJed Brown 
136ef3c5b88SJed Brown /*MC
137ef3c5b88SJed Brown      TSROSWRODAS3 - Four stage third order L-stable Rosenbrock scheme
138ef3c5b88SJed Brown 
139ef3c5b88SJed Brown      By default, the Jacobian is only recomputed once per step.
140ef3c5b88SJed Brown 
141ef3c5b88SJed Brown      Both the third order and embedded second order methods are stiffly accurate and L-stable.
142ef3c5b88SJed Brown 
143ef3c5b88SJed Brown      References:
144606c0280SSatish Balay .  * - Sandu et al, Benchmarking stiff ODE solvers for atmospheric chemistry problems II, Rosenbrock solvers, 1997.
145ef3c5b88SJed Brown 
146ef3c5b88SJed Brown      Level: intermediate
147ef3c5b88SJed Brown 
148ef3c5b88SJed Brown .seealso: TSROSW, TSROSWSANDU3
149ef3c5b88SJed Brown M*/
150ef3c5b88SJed Brown 
151ef3c5b88SJed Brown /*MC
152ef3c5b88SJed Brown      TSROSWSANDU3 - Three stage third order L-stable Rosenbrock scheme
153ef3c5b88SJed Brown 
154ef3c5b88SJed Brown      By default, the Jacobian is only recomputed once per step.
155ef3c5b88SJed Brown 
156ef3c5b88SJed Brown      The third order method is L-stable, but not stiffly accurate.
157ef3c5b88SJed Brown      The second order embedded method is strongly A-stable with R(infty) = 0.5.
158ef3c5b88SJed Brown      The internal stages are L-stable.
159ef3c5b88SJed Brown      This method is called ROS3 in the paper.
160ef3c5b88SJed Brown 
161ef3c5b88SJed Brown      References:
162606c0280SSatish Balay .  * - Sandu et al, Benchmarking stiff ODE solvers for atmospheric chemistry problems II, Rosenbrock solvers, 1997.
163ef3c5b88SJed Brown 
164ef3c5b88SJed Brown      Level: intermediate
165ef3c5b88SJed Brown 
166ef3c5b88SJed Brown .seealso: TSROSW, TSROSWRODAS3
167ef3c5b88SJed Brown M*/
168ef3c5b88SJed Brown 
169961f28d0SJed Brown /*MC
170961f28d0SJed Brown      TSROSWASSP3P3S1C - A-stable Rosenbrock-W method with SSP explicit part, third order, three stages
171961f28d0SJed Brown 
172961f28d0SJed Brown      By default, the Jacobian is only recomputed once per step.
173961f28d0SJed Brown 
174961f28d0SJed Brown      A-stable SPP explicit order 3, 3 stages, CFL 1 (eff = 1/3)
175961f28d0SJed Brown 
176961f28d0SJed Brown      References:
177606c0280SSatish Balay . * - Emil Constantinescu
178961f28d0SJed Brown 
179961f28d0SJed Brown      Level: intermediate
180961f28d0SJed Brown 
18143b21953SEmil Constantinescu .seealso: TSROSW, TSROSWLASSP3P4S2C, TSROSWLLSSP3P4S2C, SSP
182961f28d0SJed Brown M*/
183961f28d0SJed Brown 
184961f28d0SJed Brown /*MC
185998eb97aSJed Brown      TSROSWLASSP3P4S2C - L-stable Rosenbrock-W method with SSP explicit part, third order, four stages
186961f28d0SJed Brown 
187961f28d0SJed Brown      By default, the Jacobian is only recomputed once per step.
188961f28d0SJed Brown 
189961f28d0SJed Brown      L-stable (A-stable embedded) SPP explicit order 3, 4 stages, CFL 2 (eff = 1/2)
190961f28d0SJed Brown 
191961f28d0SJed Brown      References:
192606c0280SSatish Balay . * - Emil Constantinescu
193961f28d0SJed Brown 
194961f28d0SJed Brown      Level: intermediate
195961f28d0SJed Brown 
19643b21953SEmil Constantinescu .seealso: TSROSW, TSROSWASSP3P3S1C, TSROSWLLSSP3P4S2C, TSSSP
197961f28d0SJed Brown M*/
198961f28d0SJed Brown 
199961f28d0SJed Brown /*MC
200998eb97aSJed Brown      TSROSWLLSSP3P4S2C - L-stable Rosenbrock-W method with SSP explicit part, third order, four stages
201961f28d0SJed Brown 
202961f28d0SJed Brown      By default, the Jacobian is only recomputed once per step.
203961f28d0SJed Brown 
204961f28d0SJed Brown      L-stable (L-stable embedded) SPP explicit order 3, 4 stages, CFL 2 (eff = 1/2)
205961f28d0SJed Brown 
206961f28d0SJed Brown      References:
207606c0280SSatish Balay . * - Emil Constantinescu
208961f28d0SJed Brown 
209961f28d0SJed Brown      Level: intermediate
210961f28d0SJed Brown 
211961f28d0SJed Brown .seealso: TSROSW, TSROSWASSP3P3S1C, TSROSWLASSP3P4S2C, TSSSP
212961f28d0SJed Brown M*/
213961f28d0SJed Brown 
21442faf41dSJed Brown /*MC
21542faf41dSJed Brown      TSROSWGRK4T - four stage, fourth order Rosenbrock (not W) method from Kaps and Rentrop
21642faf41dSJed Brown 
21742faf41dSJed Brown      By default, the Jacobian is only recomputed once per step.
21842faf41dSJed Brown 
21942faf41dSJed Brown      A(89.3 degrees)-stable, |R(infty)| = 0.454.
22042faf41dSJed Brown 
22142faf41dSJed Brown      This method does not provide a dense output formula.
22242faf41dSJed Brown 
22342faf41dSJed Brown      References:
224606c0280SSatish Balay +   * -  Kaps and Rentrop, Generalized Runge Kutta methods of order four with stepsize control for stiff ordinary differential equations, 1979.
225606c0280SSatish Balay -   * -  Hairer and Wanner, Solving Ordinary Differential Equations II, Section 4 Table 7.2.
22642faf41dSJed Brown 
22742faf41dSJed Brown      Hairer's code ros4.f
22842faf41dSJed Brown 
22942faf41dSJed Brown      Level: intermediate
23042faf41dSJed Brown 
23142faf41dSJed Brown .seealso: TSROSW, TSROSWSHAMP4, TSROSWVELDD4, TSROSW4L
23242faf41dSJed Brown M*/
23342faf41dSJed Brown 
23442faf41dSJed Brown /*MC
23542faf41dSJed Brown      TSROSWSHAMP4 - four stage, fourth order Rosenbrock (not W) method from Shampine
23642faf41dSJed Brown 
23742faf41dSJed Brown      By default, the Jacobian is only recomputed once per step.
23842faf41dSJed Brown 
23942faf41dSJed Brown      A-stable, |R(infty)| = 1/3.
24042faf41dSJed Brown 
24142faf41dSJed Brown      This method does not provide a dense output formula.
24242faf41dSJed Brown 
24342faf41dSJed Brown      References:
244606c0280SSatish Balay +   * -  Shampine, Implementation of Rosenbrock methods, 1982.
245606c0280SSatish Balay -   * -  Hairer and Wanner, Solving Ordinary Differential Equations II, Section 4 Table 7.2.
24642faf41dSJed Brown 
24742faf41dSJed Brown      Hairer's code ros4.f
24842faf41dSJed Brown 
24942faf41dSJed Brown      Level: intermediate
25042faf41dSJed Brown 
25142faf41dSJed Brown .seealso: TSROSW, TSROSWGRK4T, TSROSWVELDD4, TSROSW4L
25242faf41dSJed Brown M*/
25342faf41dSJed Brown 
25442faf41dSJed Brown /*MC
25542faf41dSJed Brown      TSROSWVELDD4 - four stage, fourth order Rosenbrock (not W) method from van Veldhuizen
25642faf41dSJed Brown 
25742faf41dSJed Brown      By default, the Jacobian is only recomputed once per step.
25842faf41dSJed Brown 
25942faf41dSJed Brown      A(89.5 degrees)-stable, |R(infty)| = 0.24.
26042faf41dSJed Brown 
26142faf41dSJed Brown      This method does not provide a dense output formula.
26242faf41dSJed Brown 
26342faf41dSJed Brown      References:
264606c0280SSatish Balay +   * -  van Veldhuizen, D stability and Kaps Rentrop methods, 1984.
265606c0280SSatish Balay -   * -  Hairer and Wanner, Solving Ordinary Differential Equations II, Section 4 Table 7.2.
26642faf41dSJed Brown 
26742faf41dSJed Brown      Hairer's code ros4.f
26842faf41dSJed Brown 
26942faf41dSJed Brown      Level: intermediate
27042faf41dSJed Brown 
27142faf41dSJed Brown .seealso: TSROSW, TSROSWGRK4T, TSROSWSHAMP4, TSROSW4L
27242faf41dSJed Brown M*/
27342faf41dSJed Brown 
27442faf41dSJed Brown /*MC
27542faf41dSJed Brown      TSROSW4L - four stage, fourth order Rosenbrock (not W) method
27642faf41dSJed Brown 
27742faf41dSJed Brown      By default, the Jacobian is only recomputed once per step.
27842faf41dSJed Brown 
27942faf41dSJed Brown      A-stable and L-stable
28042faf41dSJed Brown 
28142faf41dSJed Brown      This method does not provide a dense output formula.
28242faf41dSJed Brown 
28342faf41dSJed Brown      References:
284606c0280SSatish Balay .  * -   Hairer and Wanner, Solving Ordinary Differential Equations II, Section 4 Table 7.2.
28542faf41dSJed Brown 
28642faf41dSJed Brown      Hairer's code ros4.f
28742faf41dSJed Brown 
28842faf41dSJed Brown      Level: intermediate
28942faf41dSJed Brown 
29042faf41dSJed Brown .seealso: TSROSW, TSROSWGRK4T, TSROSWSHAMP4, TSROSW4L
29142faf41dSJed Brown M*/
29242faf41dSJed Brown 
293e27a552bSJed Brown /*@C
294be5899b3SLisandro Dalcin   TSRosWRegisterAll - Registers all of the Rosenbrock-W methods in TSRosW
295e27a552bSJed Brown 
296e27a552bSJed Brown   Not Collective, but should be called by all processes which will need the schemes to be registered
297e27a552bSJed Brown 
298e27a552bSJed Brown   Level: advanced
299e27a552bSJed Brown 
300e27a552bSJed Brown .seealso:  TSRosWRegisterDestroy()
301e27a552bSJed Brown @*/
302e27a552bSJed Brown PetscErrorCode TSRosWRegisterAll(void)
303e27a552bSJed Brown {
304e27a552bSJed Brown   PetscFunctionBegin;
305e27a552bSJed Brown   if (TSRosWRegisterAllCalled) PetscFunctionReturn(0);
306e27a552bSJed Brown   TSRosWRegisterAllCalled = PETSC_TRUE;
307e27a552bSJed Brown 
308e27a552bSJed Brown   {
309bbd56ea5SKarl Rupp     const PetscReal A = 0;
310bbd56ea5SKarl Rupp     const PetscReal Gamma = 1;
311bbd56ea5SKarl Rupp     const PetscReal b = 1;
312bbd56ea5SKarl Rupp     const PetscReal binterpt=1;
3131f80e275SEmil Constantinescu 
3149566063dSJacob Faibussowitsch     PetscCall(TSRosWRegister(TSROSWTHETA1,1,1,&A,&Gamma,&b,NULL,1,&binterpt));
3153606a31eSEmil Constantinescu   }
3163606a31eSEmil Constantinescu 
3173606a31eSEmil Constantinescu   {
318bbd56ea5SKarl Rupp     const PetscReal A = 0;
319bbd56ea5SKarl Rupp     const PetscReal Gamma = 0.5;
320bbd56ea5SKarl Rupp     const PetscReal b = 1;
321bbd56ea5SKarl Rupp     const PetscReal binterpt=1;
322bbd56ea5SKarl Rupp 
3239566063dSJacob Faibussowitsch     PetscCall(TSRosWRegister(TSROSWTHETA2,2,1,&A,&Gamma,&b,NULL,1,&binterpt));
3243606a31eSEmil Constantinescu   }
3253606a31eSEmil Constantinescu 
3263606a31eSEmil Constantinescu   {
327da80777bSKarl 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. */
328e27a552bSJed Brown     const PetscReal
32961692a83SJed Brown       A[2][2]     = {{0,0}, {1.,0}},
330da80777bSKarl Rupp       Gamma[2][2] = {{1.707106781186547524401,0}, {-2.*1.707106781186547524401,1.707106781186547524401}},
3311c3436cfSJed Brown       b[2]        = {0.5,0.5},
3321c3436cfSJed Brown       b1[2]       = {1.0,0.0};
3331f80e275SEmil Constantinescu     PetscReal binterpt[2][2];
334da80777bSKarl Rupp     binterpt[0][0] = 1.707106781186547524401 - 1.0;
335da80777bSKarl Rupp     binterpt[1][0] = 2.0 - 1.707106781186547524401;
336da80777bSKarl Rupp     binterpt[0][1] = 1.707106781186547524401 - 1.5;
337da80777bSKarl Rupp     binterpt[1][1] = 1.5 - 1.707106781186547524401;
338bbd56ea5SKarl Rupp 
3399566063dSJacob Faibussowitsch     PetscCall(TSRosWRegister(TSROSW2P,2,2,&A[0][0],&Gamma[0][0],b,b1,2,&binterpt[0][0]));
340e27a552bSJed Brown   }
341e27a552bSJed Brown   {
342da80777bSKarl 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. */
343e27a552bSJed Brown     const PetscReal
34461692a83SJed Brown       A[2][2]     = {{0,0}, {1.,0}},
345da80777bSKarl Rupp       Gamma[2][2] = {{0.2928932188134524755992,0}, {-2.*0.2928932188134524755992,0.2928932188134524755992}},
3461c3436cfSJed Brown       b[2]        = {0.5,0.5},
3471c3436cfSJed Brown       b1[2]       = {1.0,0.0};
3481f80e275SEmil Constantinescu     PetscReal binterpt[2][2];
349da80777bSKarl Rupp     binterpt[0][0] = 0.2928932188134524755992 - 1.0;
350da80777bSKarl Rupp     binterpt[1][0] = 2.0 - 0.2928932188134524755992;
351da80777bSKarl Rupp     binterpt[0][1] = 0.2928932188134524755992 - 1.5;
352da80777bSKarl Rupp     binterpt[1][1] = 1.5 - 0.2928932188134524755992;
353bbd56ea5SKarl Rupp 
3549566063dSJacob Faibussowitsch     PetscCall(TSRosWRegister(TSROSW2M,2,2,&A[0][0],&Gamma[0][0],b,b1,2,&binterpt[0][0]));
355fe7e6d57SJed Brown   }
356fe7e6d57SJed Brown   {
357da80777bSKarl Rupp     /*const PetscReal g = 7.8867513459481287e-01; Directly written in-place below */
3581f80e275SEmil Constantinescu     PetscReal binterpt[3][2];
359fe7e6d57SJed Brown     const PetscReal
360fe7e6d57SJed Brown       A[3][3] = {{0,0,0},
361fe7e6d57SJed Brown                  {1.5773502691896257e+00,0,0},
362fe7e6d57SJed Brown                  {0.5,0,0}},
363da80777bSKarl Rupp       Gamma[3][3] = {{7.8867513459481287e-01,0,0},
364da80777bSKarl Rupp                      {-1.5773502691896257e+00,7.8867513459481287e-01,0},
365da80777bSKarl Rupp                      {-6.7075317547305480e-01,-1.7075317547305482e-01,7.8867513459481287e-01}},
366fe7e6d57SJed Brown       b[3]  = {1.0566243270259355e-01,4.9038105676657971e-02,8.4529946162074843e-01},
367fe7e6d57SJed Brown       b2[3] = {-1.7863279495408180e-01,1./3.,8.4529946162074843e-01};
3681f80e275SEmil Constantinescu 
3691f80e275SEmil Constantinescu       binterpt[0][0] = -0.8094010767585034;
3701f80e275SEmil Constantinescu       binterpt[1][0] = -0.5;
3711f80e275SEmil Constantinescu       binterpt[2][0] = 2.3094010767585034;
3721f80e275SEmil Constantinescu       binterpt[0][1] = 0.9641016151377548;
3731f80e275SEmil Constantinescu       binterpt[1][1] = 0.5;
3741f80e275SEmil Constantinescu       binterpt[2][1] = -1.4641016151377548;
375bbd56ea5SKarl Rupp 
3769566063dSJacob Faibussowitsch       PetscCall(TSRosWRegister(TSROSWRA3PW,3,3,&A[0][0],&Gamma[0][0],b,b2,2,&binterpt[0][0]));
377fe7e6d57SJed Brown   }
378fe7e6d57SJed Brown   {
3793ca35412SEmil Constantinescu     PetscReal  binterpt[4][3];
380da80777bSKarl Rupp     /*const PetscReal g = 4.3586652150845900e-01; Directly written in-place below */
381fe7e6d57SJed Brown     const PetscReal
382fe7e6d57SJed Brown       A[4][4] = {{0,0,0,0},
383fe7e6d57SJed Brown                  {8.7173304301691801e-01,0,0,0},
384fe7e6d57SJed Brown                  {8.4457060015369423e-01,-1.1299064236484185e-01,0,0},
385fe7e6d57SJed Brown                  {0,0,1.,0}},
386da80777bSKarl Rupp       Gamma[4][4] = {{4.3586652150845900e-01,0,0,0},
387da80777bSKarl Rupp                      {-8.7173304301691801e-01,4.3586652150845900e-01,0,0},
388da80777bSKarl Rupp                      {-9.0338057013044082e-01,5.4180672388095326e-02,4.3586652150845900e-01,0},
389da80777bSKarl Rupp                      {2.4212380706095346e-01,-1.2232505839045147e+00,5.4526025533510214e-01,4.3586652150845900e-01}},
390fe7e6d57SJed Brown       b[4]  = {2.4212380706095346e-01,-1.2232505839045147e+00,1.5452602553351020e+00,4.3586652150845900e-01},
3913ca35412SEmil Constantinescu       b2[4] = {3.7810903145819369e-01,-9.6042292212423178e-02,5.0000000000000000e-01,2.1793326075422950e-01};
3923ca35412SEmil Constantinescu 
3933ca35412SEmil Constantinescu     binterpt[0][0]=1.0564298455794094;
3943ca35412SEmil Constantinescu     binterpt[1][0]=2.296429974281067;
3953ca35412SEmil Constantinescu     binterpt[2][0]=-1.307599564525376;
3963ca35412SEmil Constantinescu     binterpt[3][0]=-1.045260255335102;
3973ca35412SEmil Constantinescu     binterpt[0][1]=-1.3864882699759573;
3983ca35412SEmil Constantinescu     binterpt[1][1]=-8.262611700275677;
3993ca35412SEmil Constantinescu     binterpt[2][1]=7.250979895056055;
4003ca35412SEmil Constantinescu     binterpt[3][1]=2.398120075195581;
4013ca35412SEmil Constantinescu     binterpt[0][2]=0.5721822314575016;
4023ca35412SEmil Constantinescu     binterpt[1][2]=4.742931142090097;
4033ca35412SEmil Constantinescu     binterpt[2][2]=-4.398120075195578;
4043ca35412SEmil Constantinescu     binterpt[3][2]=-0.9169932983520199;
4053ca35412SEmil Constantinescu 
4069566063dSJacob Faibussowitsch     PetscCall(TSRosWRegister(TSROSWRA34PW2,3,4,&A[0][0],&Gamma[0][0],b,b2,3,&binterpt[0][0]));
407e27a552bSJed Brown   }
408ef3c5b88SJed Brown   {
409da80777bSKarl Rupp     /* const PetscReal g = 0.5;       Directly written in-place below */
410ef3c5b88SJed Brown     const PetscReal
411ef3c5b88SJed Brown       A[4][4] = {{0,0,0,0},
412ef3c5b88SJed Brown                  {0,0,0,0},
413ef3c5b88SJed Brown                  {1.,0,0,0},
414ef3c5b88SJed Brown                  {0.75,-0.25,0.5,0}},
415da80777bSKarl Rupp       Gamma[4][4] = {{0.5,0,0,0},
416da80777bSKarl Rupp                      {1.,0.5,0,0},
417da80777bSKarl Rupp                      {-0.25,-0.25,0.5,0},
418da80777bSKarl Rupp                      {1./12,1./12,-2./3,0.5}},
419ef3c5b88SJed Brown       b[4]  = {5./6,-1./6,-1./6,0.5},
420ef3c5b88SJed Brown       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   {
425da80777bSKarl Rupp     /*const PetscReal g = 0.43586652150845899941601945119356;       Directly written in-place below */
426ef3c5b88SJed Brown     const PetscReal
427ef3c5b88SJed Brown       A[3][3] = {{0,0,0},
428da80777bSKarl Rupp                  {0.43586652150845899941601945119356,0,0},
429da80777bSKarl Rupp                  {0.43586652150845899941601945119356,0,0}},
430da80777bSKarl Rupp       Gamma[3][3] = {{0.43586652150845899941601945119356,0,0},
431da80777bSKarl Rupp                      {-0.19294655696029095575009695436041,0.43586652150845899941601945119356,0},
432da80777bSKarl Rupp                      {0,1.74927148125794685173529749738960,0.43586652150845899941601945119356}},
433ef3c5b88SJed Brown       b[3]  = {-0.75457412385404315829818998646589,1.94100407061964420292840123379419,-0.18642994676560104463021124732829},
434ef3c5b88SJed Brown       b2[3] = {-1.53358745784149585370766523913002,2.81745131148625772213931745457622,-0.28386385364476186843165221544619};
4351f80e275SEmil Constantinescu 
4361f80e275SEmil Constantinescu     PetscReal binterpt[3][2];
4371f80e275SEmil Constantinescu     binterpt[0][0] = 3.793692883777660870425141387941;
4381f80e275SEmil Constantinescu     binterpt[1][0] = -2.918692883777660870425141387941;
4391f80e275SEmil Constantinescu     binterpt[2][0] = 0.125;
4401f80e275SEmil Constantinescu     binterpt[0][1] = -0.725741064379812106687651020584;
4411f80e275SEmil Constantinescu     binterpt[1][1] = 0.559074397713145440020984353917;
4421f80e275SEmil Constantinescu     binterpt[2][1] = 0.16666666666666666666666666666667;
4431f80e275SEmil Constantinescu 
4449566063dSJacob Faibussowitsch     PetscCall(TSRosWRegister(TSROSWSANDU3,3,3,&A[0][0],&Gamma[0][0],b,b2,2,&binterpt[0][0]));
445ef3c5b88SJed Brown   }
446b1c69cc3SEmil Constantinescu   {
447da80777bSKarl Rupp     /*const PetscReal s3 = PetscSqrtReal(3.),g = (3.0+s3)/6.0;
448da80777bSKarl Rupp      * Direct evaluation: s3 = 1.732050807568877293527;
449da80777bSKarl Rupp      *                     g = 0.7886751345948128822546;
450da80777bSKarl Rupp      * Values are directly inserted below to ensure availability at compile time (compiler warnings otherwise...) */
451b1c69cc3SEmil Constantinescu     const PetscReal
452b1c69cc3SEmil Constantinescu       A[3][3] = {{0,0,0},
453b1c69cc3SEmil Constantinescu                  {1,0,0},
454b1c69cc3SEmil Constantinescu                  {0.25,0.25,0}},
455b1c69cc3SEmil Constantinescu       Gamma[3][3] = {{0,0,0},
456da80777bSKarl Rupp                      {(-3.0-1.732050807568877293527)/6.0,0.7886751345948128822546,0},
457da80777bSKarl Rupp                      {(-3.0-1.732050807568877293527)/24.0,(-3.0-1.732050807568877293527)/8.0,0.7886751345948128822546}},
458b1c69cc3SEmil Constantinescu       b[3]  = {1./6.,1./6.,2./3.},
459b1c69cc3SEmil Constantinescu       b2[3] = {1./4.,1./4.,1./2.};
460c0cb691aSEmil Constantinescu     PetscReal binterpt[3][2];
461da80777bSKarl Rupp 
462c0cb691aSEmil Constantinescu     binterpt[0][0]=0.089316397477040902157517886164709;
463c0cb691aSEmil Constantinescu     binterpt[1][0]=-0.91068360252295909784248211383529;
464c0cb691aSEmil Constantinescu     binterpt[2][0]=1.8213672050459181956849642276706;
465c0cb691aSEmil Constantinescu     binterpt[0][1]=0.077350269189625764509148780501957;
466c0cb691aSEmil Constantinescu     binterpt[1][1]=1.077350269189625764509148780502;
467c0cb691aSEmil Constantinescu     binterpt[2][1]=-1.1547005383792515290182975610039;
468bbd56ea5SKarl Rupp 
4699566063dSJacob Faibussowitsch     PetscCall(TSRosWRegister(TSROSWASSP3P3S1C,3,3,&A[0][0],&Gamma[0][0],b,b2,2,&binterpt[0][0]));
470b1c69cc3SEmil Constantinescu   }
471b1c69cc3SEmil Constantinescu 
472b1c69cc3SEmil Constantinescu   {
473b1c69cc3SEmil Constantinescu     const PetscReal
474b1c69cc3SEmil Constantinescu       A[4][4] = {{0,0,0,0},
475b1c69cc3SEmil Constantinescu                  {1./2.,0,0,0},
476b1c69cc3SEmil Constantinescu                  {1./2.,1./2.,0,0},
477b1c69cc3SEmil Constantinescu                  {1./6.,1./6.,1./6.,0}},
478b1c69cc3SEmil Constantinescu       Gamma[4][4] = {{1./2.,0,0,0},
479b1c69cc3SEmil Constantinescu                      {0.0,1./4.,0,0},
480b1c69cc3SEmil Constantinescu                      {-2.,-2./3.,2./3.,0},
481b1c69cc3SEmil Constantinescu                      {1./2.,5./36.,-2./9,0}},
482b1c69cc3SEmil Constantinescu       b[4]  = {1./6.,1./6.,1./6.,1./2.},
483b1c69cc3SEmil Constantinescu       b2[4] = {1./8.,3./4.,1./8.,0};
484c0cb691aSEmil Constantinescu     PetscReal binterpt[4][3];
485da80777bSKarl Rupp 
486c0cb691aSEmil Constantinescu     binterpt[0][0]=6.25;
487c0cb691aSEmil Constantinescu     binterpt[1][0]=-30.25;
488c0cb691aSEmil Constantinescu     binterpt[2][0]=1.75;
489c0cb691aSEmil Constantinescu     binterpt[3][0]=23.25;
490c0cb691aSEmil Constantinescu     binterpt[0][1]=-9.75;
491c0cb691aSEmil Constantinescu     binterpt[1][1]=58.75;
492c0cb691aSEmil Constantinescu     binterpt[2][1]=-3.25;
493c0cb691aSEmil Constantinescu     binterpt[3][1]=-45.75;
494c0cb691aSEmil Constantinescu     binterpt[0][2]=3.6666666666666666666666666666667;
495c0cb691aSEmil Constantinescu     binterpt[1][2]=-28.333333333333333333333333333333;
496c0cb691aSEmil Constantinescu     binterpt[2][2]=1.6666666666666666666666666666667;
497c0cb691aSEmil Constantinescu     binterpt[3][2]=23.;
498bbd56ea5SKarl Rupp 
4999566063dSJacob Faibussowitsch     PetscCall(TSRosWRegister(TSROSWLASSP3P4S2C,3,4,&A[0][0],&Gamma[0][0],b,b2,3,&binterpt[0][0]));
500b1c69cc3SEmil Constantinescu   }
501b1c69cc3SEmil Constantinescu 
502b1c69cc3SEmil Constantinescu   {
503b1c69cc3SEmil Constantinescu     const PetscReal
504b1c69cc3SEmil Constantinescu       A[4][4] = {{0,0,0,0},
505b1c69cc3SEmil Constantinescu                  {1./2.,0,0,0},
506b1c69cc3SEmil Constantinescu                  {1./2.,1./2.,0,0},
507b1c69cc3SEmil Constantinescu                  {1./6.,1./6.,1./6.,0}},
508b1c69cc3SEmil Constantinescu       Gamma[4][4] = {{1./2.,0,0,0},
509b1c69cc3SEmil Constantinescu                      {0.0,3./4.,0,0},
510b1c69cc3SEmil Constantinescu                      {-2./3.,-23./9.,2./9.,0},
511b1c69cc3SEmil Constantinescu                      {1./18.,65./108.,-2./27,0}},
512b1c69cc3SEmil Constantinescu       b[4]  = {1./6.,1./6.,1./6.,1./2.},
513b1c69cc3SEmil Constantinescu       b2[4] = {3./16.,10./16.,3./16.,0};
514c0cb691aSEmil Constantinescu     PetscReal binterpt[4][3];
515da80777bSKarl Rupp 
516c0cb691aSEmil Constantinescu     binterpt[0][0]=1.6911764705882352941176470588235;
517c0cb691aSEmil Constantinescu     binterpt[1][0]=3.6813725490196078431372549019608;
518c0cb691aSEmil Constantinescu     binterpt[2][0]=0.23039215686274509803921568627451;
519c0cb691aSEmil Constantinescu     binterpt[3][0]=-4.6029411764705882352941176470588;
520c0cb691aSEmil Constantinescu     binterpt[0][1]=-0.95588235294117647058823529411765;
521c0cb691aSEmil Constantinescu     binterpt[1][1]=-6.2401960784313725490196078431373;
522c0cb691aSEmil Constantinescu     binterpt[2][1]=-0.31862745098039215686274509803922;
523c0cb691aSEmil Constantinescu     binterpt[3][1]=7.5147058823529411764705882352941;
524c0cb691aSEmil Constantinescu     binterpt[0][2]=-0.56862745098039215686274509803922;
525c0cb691aSEmil Constantinescu     binterpt[1][2]=2.7254901960784313725490196078431;
526c0cb691aSEmil Constantinescu     binterpt[2][2]=0.25490196078431372549019607843137;
527c0cb691aSEmil Constantinescu     binterpt[3][2]=-2.4117647058823529411764705882353;
528bbd56ea5SKarl Rupp 
5299566063dSJacob Faibussowitsch     PetscCall(TSRosWRegister(TSROSWLLSSP3P4S2C,3,4,&A[0][0],&Gamma[0][0],b,b2,3,&binterpt[0][0]));
530b1c69cc3SEmil Constantinescu   }
531753f8adbSEmil Constantinescu 
532753f8adbSEmil Constantinescu   {
533753f8adbSEmil Constantinescu     PetscReal A[4][4],Gamma[4][4],b[4],b2[4];
5343ca35412SEmil Constantinescu     PetscReal binterpt[4][3];
535753f8adbSEmil Constantinescu 
536753f8adbSEmil Constantinescu     Gamma[0][0]=0.4358665215084589994160194475295062513822671686978816;
53705e8e825SJed Brown     Gamma[0][1]=0; Gamma[0][2]=0; Gamma[0][3]=0;
538753f8adbSEmil Constantinescu     Gamma[1][0]=-1.997527830934941248426324674704153457289527280554476;
539753f8adbSEmil Constantinescu     Gamma[1][1]=0.4358665215084589994160194475295062513822671686978816;
54005e8e825SJed Brown     Gamma[1][2]=0; Gamma[1][3]=0;
541753f8adbSEmil Constantinescu     Gamma[2][0]=-1.007948511795029620852002345345404191008352770119903;
542753f8adbSEmil Constantinescu     Gamma[2][1]=-0.004648958462629345562774289390054679806993396798458131;
543753f8adbSEmil Constantinescu     Gamma[2][2]=0.4358665215084589994160194475295062513822671686978816;
54405e8e825SJed Brown     Gamma[2][3]=0;
545753f8adbSEmil Constantinescu     Gamma[3][0]=-0.6685429734233467180451604600279552604364311322650783;
546753f8adbSEmil Constantinescu     Gamma[3][1]=0.6056625986449338476089525334450053439525178740492984;
547753f8adbSEmil Constantinescu     Gamma[3][2]=-0.9717899277217721234705114616271378792182450260943198;
548753f8adbSEmil Constantinescu     Gamma[3][3]=0;
549753f8adbSEmil Constantinescu 
55005e8e825SJed Brown     A[0][0]=0; A[0][1]=0; A[0][2]=0; A[0][3]=0;
551753f8adbSEmil Constantinescu     A[1][0]=0.8717330430169179988320388950590125027645343373957631;
55205e8e825SJed Brown     A[1][1]=0; A[1][2]=0; A[1][3]=0;
553753f8adbSEmil Constantinescu     A[2][0]=0.5275890119763004115618079766722914408876108660811028;
554753f8adbSEmil Constantinescu     A[2][1]=0.07241098802369958843819203208518599088698057726988732;
55505e8e825SJed Brown     A[2][2]=0; A[2][3]=0;
556753f8adbSEmil Constantinescu     A[3][0]=0.3990960076760701320627260685975778145384666450351314;
557753f8adbSEmil Constantinescu     A[3][1]=-0.4375576546135194437228463747348862825846903771419953;
558753f8adbSEmil Constantinescu     A[3][2]=1.038461646937449311660120300601880176655352737312713;
55905e8e825SJed Brown     A[3][3]=0;
560753f8adbSEmil Constantinescu 
561753f8adbSEmil Constantinescu     b[0]=0.1876410243467238251612921333138006734899663569186926;
562753f8adbSEmil Constantinescu     b[1]=-0.5952974735769549480478230473706443582188442040780541;
563753f8adbSEmil Constantinescu     b[2]=0.9717899277217721234705114616271378792182450260943198;
564753f8adbSEmil Constantinescu     b[3]=0.4358665215084589994160194475295062513822671686978816;
565753f8adbSEmil Constantinescu 
566753f8adbSEmil Constantinescu     b2[0]=0.2147402862233891404862383521089097657790734483804460;
567753f8adbSEmil Constantinescu     b2[1]=-0.4851622638849390928209050538171743017757490232519684;
568753f8adbSEmil Constantinescu     b2[2]=0.8687250025203875511662123688667549217531982787600080;
569753f8adbSEmil Constantinescu     b2[3]=0.4016969751411624011684543450940068201770721128357014;
570753f8adbSEmil Constantinescu 
5713ca35412SEmil Constantinescu     binterpt[0][0]=2.2565812720167954547104627844105;
5723ca35412SEmil Constantinescu     binterpt[1][0]=1.349166413351089573796243820819;
5733ca35412SEmil Constantinescu     binterpt[2][0]=-2.4695174540533503758652847586647;
5743ca35412SEmil Constantinescu     binterpt[3][0]=-0.13623023131453465264142184656474;
5753ca35412SEmil Constantinescu     binterpt[0][1]=-3.0826699111559187902922463354557;
5763ca35412SEmil Constantinescu     binterpt[1][1]=-2.4689115685996042534544925650515;
5773ca35412SEmil Constantinescu     binterpt[2][1]=5.7428279814696677152129332773553;
5783ca35412SEmil Constantinescu     binterpt[3][1]=-0.19124650171414467146619437684812;
5793ca35412SEmil Constantinescu     binterpt[0][2]=1.0137296634858471607430756831148;
5803ca35412SEmil Constantinescu     binterpt[1][2]=0.52444768167155973161042570784064;
5813ca35412SEmil Constantinescu     binterpt[2][2]=-2.3015205996945452158771370439586;
5823ca35412SEmil Constantinescu     binterpt[3][2]=0.76334325453713832352363565300308;
583f4aed992SEmil Constantinescu 
5849566063dSJacob Faibussowitsch     PetscCall(TSRosWRegister(TSROSWARK3,3,4,&A[0][0],&Gamma[0][0],b,b2,3,&binterpt[0][0]));
585753f8adbSEmil Constantinescu   }
5869566063dSJacob Faibussowitsch   PetscCall(TSRosWRegisterRos4(TSROSWGRK4T,0.231,PETSC_DEFAULT,PETSC_DEFAULT,0,-0.1282612945269037e+01));
5879566063dSJacob Faibussowitsch   PetscCall(TSRosWRegisterRos4(TSROSWSHAMP4,0.5,PETSC_DEFAULT,PETSC_DEFAULT,0,125./108.));
5889566063dSJacob Faibussowitsch   PetscCall(TSRosWRegisterRos4(TSROSWVELDD4,0.22570811482256823492,PETSC_DEFAULT,PETSC_DEFAULT,0,-1.355958941201148));
5899566063dSJacob Faibussowitsch   PetscCall(TSRosWRegisterRos4(TSROSW4L,0.57282,PETSC_DEFAULT,PETSC_DEFAULT,0,-1.093502252409163));
590e27a552bSJed Brown   PetscFunctionReturn(0);
591e27a552bSJed Brown }
592e27a552bSJed Brown 
593e27a552bSJed Brown /*@C
594e27a552bSJed Brown    TSRosWRegisterDestroy - Frees the list of schemes that were registered by TSRosWRegister().
595e27a552bSJed Brown 
596e27a552bSJed Brown    Not Collective
597e27a552bSJed Brown 
598e27a552bSJed Brown    Level: advanced
599e27a552bSJed Brown 
600607a6623SBarry Smith .seealso: TSRosWRegister(), TSRosWRegisterAll()
601e27a552bSJed Brown @*/
602e27a552bSJed Brown PetscErrorCode TSRosWRegisterDestroy(void)
603e27a552bSJed Brown {
60461692a83SJed Brown   RosWTableauLink link;
605e27a552bSJed Brown 
606e27a552bSJed Brown   PetscFunctionBegin;
60761692a83SJed Brown   while ((link = RosWTableauList)) {
60861692a83SJed Brown     RosWTableau t = &link->tab;
60961692a83SJed Brown     RosWTableauList = link->next;
6109566063dSJacob Faibussowitsch     PetscCall(PetscFree5(t->A,t->Gamma,t->b,t->ASum,t->GammaSum));
6119566063dSJacob Faibussowitsch     PetscCall(PetscFree5(t->At,t->bt,t->GammaInv,t->GammaZeroDiag,t->GammaExplicitCorr));
6129566063dSJacob Faibussowitsch     PetscCall(PetscFree2(t->bembed,t->bembedt));
6139566063dSJacob Faibussowitsch     PetscCall(PetscFree(t->binterpt));
6149566063dSJacob Faibussowitsch     PetscCall(PetscFree(t->name));
6159566063dSJacob Faibussowitsch     PetscCall(PetscFree(link));
616e27a552bSJed Brown   }
617e27a552bSJed Brown   TSRosWRegisterAllCalled = PETSC_FALSE;
618e27a552bSJed Brown   PetscFunctionReturn(0);
619e27a552bSJed Brown }
620e27a552bSJed Brown 
621e27a552bSJed Brown /*@C
622e27a552bSJed Brown   TSRosWInitializePackage - This function initializes everything in the TSRosW package. It is called
6238a690491SBarry Smith   from TSInitializePackage().
624e27a552bSJed Brown 
625e27a552bSJed Brown   Level: developer
626e27a552bSJed Brown 
627e27a552bSJed Brown .seealso: PetscInitialize()
628e27a552bSJed Brown @*/
629607a6623SBarry Smith PetscErrorCode TSRosWInitializePackage(void)
630e27a552bSJed Brown {
631e27a552bSJed Brown   PetscFunctionBegin;
632e27a552bSJed Brown   if (TSRosWPackageInitialized) PetscFunctionReturn(0);
633e27a552bSJed Brown   TSRosWPackageInitialized = PETSC_TRUE;
6349566063dSJacob Faibussowitsch   PetscCall(TSRosWRegisterAll());
6359566063dSJacob Faibussowitsch   PetscCall(PetscRegisterFinalize(TSRosWFinalizePackage));
636e27a552bSJed Brown   PetscFunctionReturn(0);
637e27a552bSJed Brown }
638e27a552bSJed Brown 
639e27a552bSJed Brown /*@C
640e27a552bSJed Brown   TSRosWFinalizePackage - This function destroys everything in the TSRosW package. It is
641e27a552bSJed Brown   called from PetscFinalize().
642e27a552bSJed Brown 
643e27a552bSJed Brown   Level: developer
644e27a552bSJed Brown 
645e27a552bSJed Brown .seealso: PetscFinalize()
646e27a552bSJed Brown @*/
647e27a552bSJed Brown PetscErrorCode TSRosWFinalizePackage(void)
648e27a552bSJed Brown {
649e27a552bSJed Brown   PetscFunctionBegin;
650e27a552bSJed Brown   TSRosWPackageInitialized = PETSC_FALSE;
6519566063dSJacob Faibussowitsch   PetscCall(TSRosWRegisterDestroy());
652e27a552bSJed Brown   PetscFunctionReturn(0);
653e27a552bSJed Brown }
654e27a552bSJed Brown 
655e27a552bSJed Brown /*@C
65661692a83SJed Brown    TSRosWRegister - register a Rosenbrock W scheme by providing the entries in the Butcher tableau and optionally embedded approximations and interpolation
657e27a552bSJed Brown 
658e27a552bSJed Brown    Not Collective, but the same schemes should be registered on all processes on which they will be used
659e27a552bSJed Brown 
660e27a552bSJed Brown    Input Parameters:
661e27a552bSJed Brown +  name - identifier for method
662e27a552bSJed Brown .  order - approximation order of method
663e27a552bSJed Brown .  s - number of stages, this is the dimension of the matrices below
66461692a83SJed Brown .  A - Table of propagated stage coefficients (dimension s*s, row-major), strictly lower triangular
66561692a83SJed Brown .  Gamma - Table of coefficients in implicit stage equations (dimension s*s, row-major), lower triangular with nonzero diagonal
666fe7e6d57SJed Brown .  b - Step completion table (dimension s)
6670298fd71SBarry Smith .  bembed - Step completion table for a scheme of order one less (dimension s, NULL if no embedded scheme is available)
668f4aed992SEmil Constantinescu .  pinterp - Order of the interpolation scheme, equal to the number of columns of binterpt
66942faf41dSJed Brown -  binterpt - Coefficients of the interpolation formula (dimension s*pinterp)
670e27a552bSJed Brown 
671e27a552bSJed Brown    Notes:
67261692a83SJed Brown    Several Rosenbrock W methods are provided, this function is only needed to create new methods.
673e27a552bSJed Brown 
674e27a552bSJed Brown    Level: advanced
675e27a552bSJed Brown 
676e27a552bSJed Brown .seealso: TSRosW
677e27a552bSJed Brown @*/
678f9c1d6abSBarry Smith PetscErrorCode TSRosWRegister(TSRosWType name,PetscInt order,PetscInt s,const PetscReal A[],const PetscReal Gamma[],const PetscReal b[],const PetscReal bembed[],
679f4aed992SEmil Constantinescu                               PetscInt pinterp,const PetscReal binterpt[])
680e27a552bSJed Brown {
68161692a83SJed Brown   RosWTableauLink link;
68261692a83SJed Brown   RosWTableau     t;
68361692a83SJed Brown   PetscInt        i,j,k;
68461692a83SJed Brown   PetscScalar     *GammaInv;
685e27a552bSJed Brown 
686e27a552bSJed Brown   PetscFunctionBegin;
687fe7e6d57SJed Brown   PetscValidCharPointer(name,1);
688dadcf809SJacob Faibussowitsch   PetscValidRealPointer(A,4);
689dadcf809SJacob Faibussowitsch   PetscValidRealPointer(Gamma,5);
690dadcf809SJacob Faibussowitsch   PetscValidRealPointer(b,6);
691dadcf809SJacob Faibussowitsch   if (bembed) PetscValidRealPointer(bembed,7);
692fe7e6d57SJed Brown 
6939566063dSJacob Faibussowitsch   PetscCall(TSRosWInitializePackage());
6949566063dSJacob Faibussowitsch   PetscCall(PetscNew(&link));
695e27a552bSJed Brown   t        = &link->tab;
6969566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(name,&t->name));
697e27a552bSJed Brown   t->order = order;
698e27a552bSJed Brown   t->s     = s;
6999566063dSJacob Faibussowitsch   PetscCall(PetscMalloc5(s*s,&t->A,s*s,&t->Gamma,s,&t->b,s,&t->ASum,s,&t->GammaSum));
7009566063dSJacob Faibussowitsch   PetscCall(PetscMalloc5(s*s,&t->At,s,&t->bt,s*s,&t->GammaInv,s,&t->GammaZeroDiag,s*s,&t->GammaExplicitCorr));
7019566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(t->A,A,s*s));
7029566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(t->Gamma,Gamma,s*s));
7039566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(t->GammaExplicitCorr,Gamma,s*s));
7049566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(t->b,b,s));
705fe7e6d57SJed Brown   if (bembed) {
7069566063dSJacob Faibussowitsch     PetscCall(PetscMalloc2(s,&t->bembed,s,&t->bembedt));
7079566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(t->bembed,bembed,s));
708fe7e6d57SJed Brown   }
70961692a83SJed Brown   for (i=0; i<s; i++) {
71061692a83SJed Brown     t->ASum[i]     = 0;
71161692a83SJed Brown     t->GammaSum[i] = 0;
71261692a83SJed Brown     for (j=0; j<s; j++) {
71361692a83SJed Brown       t->ASum[i]     += A[i*s+j];
714fe7e6d57SJed Brown       t->GammaSum[i] += Gamma[i*s+j];
71561692a83SJed Brown     }
71661692a83SJed Brown   }
7179566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(s*s,&GammaInv)); /* Need to use Scalar for inverse, then convert back to Real */
71861692a83SJed Brown   for (i=0; i<s*s; i++) GammaInv[i] = Gamma[i];
719fd96d5b0SEmil Constantinescu   for (i=0; i<s; i++) {
720fd96d5b0SEmil Constantinescu     if (Gamma[i*s+i] == 0.0) {
721fd96d5b0SEmil Constantinescu       GammaInv[i*s+i] = 1.0;
722c17803e7SJed Brown       t->GammaZeroDiag[i] = PETSC_TRUE;
723fd96d5b0SEmil Constantinescu     } else {
724c17803e7SJed Brown       t->GammaZeroDiag[i] = PETSC_FALSE;
725fd96d5b0SEmil Constantinescu     }
726fd96d5b0SEmil Constantinescu   }
727fd96d5b0SEmil Constantinescu 
72861692a83SJed Brown   switch (s) {
72961692a83SJed Brown   case 1: GammaInv[0] = 1./GammaInv[0]; break;
7309566063dSJacob Faibussowitsch   case 2: PetscCall(PetscKernel_A_gets_inverse_A_2(GammaInv,0,PETSC_FALSE,NULL)); break;
7319566063dSJacob Faibussowitsch   case 3: PetscCall(PetscKernel_A_gets_inverse_A_3(GammaInv,0,PETSC_FALSE,NULL)); break;
7329566063dSJacob Faibussowitsch   case 4: PetscCall(PetscKernel_A_gets_inverse_A_4(GammaInv,0,PETSC_FALSE,NULL)); break;
73361692a83SJed Brown   case 5: {
73461692a83SJed Brown     PetscInt  ipvt5[5];
73561692a83SJed Brown     MatScalar work5[5*5];
7369566063dSJacob Faibussowitsch     PetscCall(PetscKernel_A_gets_inverse_A_5(GammaInv,ipvt5,work5,0,PETSC_FALSE,NULL)); break;
73761692a83SJed Brown   }
7389566063dSJacob Faibussowitsch   case 6: PetscCall(PetscKernel_A_gets_inverse_A_6(GammaInv,0,PETSC_FALSE,NULL)); break;
7399566063dSJacob Faibussowitsch   case 7: PetscCall(PetscKernel_A_gets_inverse_A_7(GammaInv,0,PETSC_FALSE,NULL)); break;
74098921bdaSJacob Faibussowitsch   default: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented for %D stages",s);
74161692a83SJed Brown   }
74261692a83SJed Brown   for (i=0; i<s*s; i++) t->GammaInv[i] = PetscRealPart(GammaInv[i]);
7439566063dSJacob Faibussowitsch   PetscCall(PetscFree(GammaInv));
74443b21953SEmil Constantinescu 
74543b21953SEmil Constantinescu   for (i=0; i<s; i++) {
74643b21953SEmil Constantinescu     for (k=0; k<i+1; k++) {
74743b21953SEmil Constantinescu       t->GammaExplicitCorr[i*s+k]=(t->GammaExplicitCorr[i*s+k])*(t->GammaInv[k*s+k]);
74843b21953SEmil Constantinescu       for (j=k+1; j<i+1; j++) {
74943b21953SEmil Constantinescu         t->GammaExplicitCorr[i*s+k]+=(t->GammaExplicitCorr[i*s+j])*(t->GammaInv[j*s+k]);
75043b21953SEmil Constantinescu       }
75143b21953SEmil Constantinescu     }
75243b21953SEmil Constantinescu   }
75343b21953SEmil Constantinescu 
75461692a83SJed Brown   for (i=0; i<s; i++) {
75561692a83SJed Brown     for (j=0; j<s; j++) {
75661692a83SJed Brown       t->At[i*s+j] = 0;
75761692a83SJed Brown       for (k=0; k<s; k++) {
75861692a83SJed Brown         t->At[i*s+j] += t->A[i*s+k] * t->GammaInv[k*s+j];
75961692a83SJed Brown       }
76061692a83SJed Brown     }
76161692a83SJed Brown     t->bt[i] = 0;
76261692a83SJed Brown     for (j=0; j<s; j++) {
76361692a83SJed Brown       t->bt[i] += t->b[j] * t->GammaInv[j*s+i];
76461692a83SJed Brown     }
765fe7e6d57SJed Brown     if (bembed) {
766fe7e6d57SJed Brown       t->bembedt[i] = 0;
767fe7e6d57SJed Brown       for (j=0; j<s; j++) {
768fe7e6d57SJed Brown         t->bembedt[i] += t->bembed[j] * t->GammaInv[j*s+i];
769fe7e6d57SJed Brown       }
770fe7e6d57SJed Brown     }
77161692a83SJed Brown   }
7728d59e960SJed Brown   t->ccfl = 1.0;                /* Fix this */
7738d59e960SJed Brown 
774f4aed992SEmil Constantinescu   t->pinterp = pinterp;
7759566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(s*pinterp,&t->binterpt));
7769566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(t->binterpt,binterpt,s*pinterp));
77761692a83SJed Brown   link->next = RosWTableauList;
77861692a83SJed Brown   RosWTableauList = link;
779e27a552bSJed Brown   PetscFunctionReturn(0);
780e27a552bSJed Brown }
781e27a552bSJed Brown 
78242faf41dSJed Brown /*@C
783fd292e60Sprj-    TSRosWRegisterRos4 - register a fourth order Rosenbrock scheme by providing parameter choices
78442faf41dSJed Brown 
78542faf41dSJed Brown    Not Collective, but the same schemes should be registered on all processes on which they will be used
78642faf41dSJed Brown 
78742faf41dSJed Brown    Input Parameters:
78842faf41dSJed Brown +  name - identifier for method
78942faf41dSJed Brown .  gamma - leading coefficient (diagonal entry)
79042faf41dSJed Brown .  a2 - design parameter, see Table 7.2 of Hairer&Wanner
79142faf41dSJed Brown .  a3 - design parameter or PETSC_DEFAULT to satisfy one of the order five conditions (Eq 7.22)
79242faf41dSJed Brown .  b3 - design parameter, see Table 7.2 of Hairer&Wanner
79342faf41dSJed Brown .  beta43 - design parameter or PETSC_DEFAULT to use Equation 7.21 of Hairer&Wanner
794a2b725a8SWilliam Gropp -  e4 - design parameter for embedded method, see coefficient E4 in ros4.f code from Hairer
79542faf41dSJed Brown 
79642faf41dSJed Brown    Notes:
79742faf41dSJed Brown    This routine encodes the design of fourth order Rosenbrock methods as described in Hairer and Wanner volume 2.
79842faf41dSJed Brown    It is used here to implement several methods from the book and can be used to experiment with new methods.
79942faf41dSJed Brown    It was written this way instead of by copying coefficients in order to provide better than double precision satisfaction of the order conditions.
80042faf41dSJed Brown 
80142faf41dSJed Brown    Level: developer
80242faf41dSJed Brown 
80342faf41dSJed Brown .seealso: TSRosW, TSRosWRegister()
80442faf41dSJed Brown @*/
80519fd82e9SBarry Smith PetscErrorCode TSRosWRegisterRos4(TSRosWType name,PetscReal gamma,PetscReal a2,PetscReal a3,PetscReal b3,PetscReal e4)
80642faf41dSJed Brown {
80742faf41dSJed Brown   /* Declare numeric constants so they can be quad precision without being truncated at double */
80842faf41dSJed Brown   const PetscReal one = 1,two = 2,three = 3,four = 4,five = 5,six = 6,eight = 8,twelve = 12,twenty = 20,twentyfour = 24,
80942faf41dSJed Brown     p32 = one/six - gamma + gamma*gamma,
81042faf41dSJed Brown     p42 = one/eight - gamma/three,
81142faf41dSJed Brown     p43 = one/twelve - gamma/three,
81242faf41dSJed Brown     p44 = one/twentyfour - gamma/two + three/two*gamma*gamma - gamma*gamma*gamma,
81342faf41dSJed Brown     p56 = one/twenty - gamma/four;
81442faf41dSJed Brown   PetscReal   a4,a32,a42,a43,b1,b2,b4,beta2p,beta3p,beta4p,beta32,beta42,beta43,beta32beta2p,beta4jbetajp;
81542faf41dSJed Brown   PetscReal   A[4][4],Gamma[4][4],b[4],bm[4];
81642faf41dSJed Brown   PetscScalar M[3][3],rhs[3];
81742faf41dSJed Brown 
81842faf41dSJed Brown   PetscFunctionBegin;
81942faf41dSJed Brown   /* Step 1: choose Gamma (input) */
82042faf41dSJed Brown   /* Step 2: choose a2,a3,a4; b1,b2,b3,b4 to satisfy order conditions */
82142faf41dSJed Brown   if (a3 == PETSC_DEFAULT) a3 = (one/five - a2/four)/(one/four - a2/three); /* Eq 7.22 */
82242faf41dSJed Brown   a4 = a3;                                                  /* consequence of 7.20 */
82342faf41dSJed Brown 
82442faf41dSJed Brown   /* Solve order conditions 7.15a, 7.15c, 7.15e */
82542faf41dSJed Brown   M[0][0] = one; M[0][1] = one;      M[0][2] = one;      /* 7.15a */
82642faf41dSJed Brown   M[1][0] = 0.0; M[1][1] = a2*a2;    M[1][2] = a4*a4;    /* 7.15c */
82742faf41dSJed Brown   M[2][0] = 0.0; M[2][1] = a2*a2*a2; M[2][2] = a4*a4*a4; /* 7.15e */
82842faf41dSJed Brown   rhs[0]  = one - b3;
82942faf41dSJed Brown   rhs[1]  = one/three - a3*a3*b3;
83042faf41dSJed Brown   rhs[2]  = one/four - a3*a3*a3*b3;
8319566063dSJacob Faibussowitsch   PetscCall(PetscKernel_A_gets_inverse_A_3(&M[0][0],0,PETSC_FALSE,NULL));
83242faf41dSJed Brown   b1      = PetscRealPart(M[0][0]*rhs[0] + M[0][1]*rhs[1] + M[0][2]*rhs[2]);
83342faf41dSJed Brown   b2      = PetscRealPart(M[1][0]*rhs[0] + M[1][1]*rhs[1] + M[1][2]*rhs[2]);
83442faf41dSJed Brown   b4      = PetscRealPart(M[2][0]*rhs[0] + M[2][1]*rhs[1] + M[2][2]*rhs[2]);
83542faf41dSJed Brown 
83642faf41dSJed Brown   /* Step 3 */
83742faf41dSJed Brown   beta43       = (p56 - a2*p43) / (b4*a3*a3*(a3 - a2)); /* 7.21 */
83842faf41dSJed Brown   beta32beta2p =  p44 / (b4*beta43);                    /* 7.15h */
83942faf41dSJed Brown   beta4jbetajp = (p32 - b3*beta32beta2p) / b4;
84042faf41dSJed Brown   M[0][0]      = b2;                                    M[0][1] = b3;                 M[0][2] = b4;
84142faf41dSJed Brown   M[1][0]      = a4*a4*beta32beta2p-a3*a3*beta4jbetajp; M[1][1] = a2*a2*beta4jbetajp; M[1][2] = -a2*a2*beta32beta2p;
84242faf41dSJed Brown   M[2][0]      = b4*beta43*a3*a3-p43;                   M[2][1] = -b4*beta43*a2*a2;   M[2][2] = 0;
84342faf41dSJed Brown   rhs[0]       = one/two - gamma; rhs[1] = 0; rhs[2] = -a2*a2*p32;
8449566063dSJacob Faibussowitsch   PetscCall(PetscKernel_A_gets_inverse_A_3(&M[0][0],0,PETSC_FALSE,NULL));
84542faf41dSJed Brown   beta2p       = PetscRealPart(M[0][0]*rhs[0] + M[0][1]*rhs[1] + M[0][2]*rhs[2]);
84642faf41dSJed Brown   beta3p       = PetscRealPart(M[1][0]*rhs[0] + M[1][1]*rhs[1] + M[1][2]*rhs[2]);
84742faf41dSJed Brown   beta4p       = PetscRealPart(M[2][0]*rhs[0] + M[2][1]*rhs[1] + M[2][2]*rhs[2]);
84842faf41dSJed Brown 
84942faf41dSJed Brown   /* Step 4: back-substitute */
85042faf41dSJed Brown   beta32 = beta32beta2p / beta2p;
85142faf41dSJed Brown   beta42 = (beta4jbetajp - beta43*beta3p) / beta2p;
85242faf41dSJed Brown 
85342faf41dSJed Brown   /* Step 5: 7.15f and 7.20, then 7.16 */
85442faf41dSJed Brown   a43 = 0;
85542faf41dSJed Brown   a32 = p42 / (b3*a3*beta2p + b4*a4*beta2p);
85642faf41dSJed Brown   a42 = a32;
85742faf41dSJed Brown 
85842faf41dSJed Brown   A[0][0]     = 0;          A[0][1] = 0;   A[0][2] = 0;   A[0][3] = 0;
85942faf41dSJed Brown   A[1][0]     = a2;         A[1][1] = 0;   A[1][2] = 0;   A[1][3] = 0;
86042faf41dSJed Brown   A[2][0]     = a3-a32;     A[2][1] = a32; A[2][2] = 0;   A[2][3] = 0;
86142faf41dSJed Brown   A[3][0]     = a4-a43-a42; A[3][1] = a42; A[3][2] = a43; A[3][3] = 0;
86242faf41dSJed Brown   Gamma[0][0] = gamma;                        Gamma[0][1] = 0;              Gamma[0][2] = 0;              Gamma[0][3] = 0;
86342faf41dSJed Brown   Gamma[1][0] = beta2p-A[1][0];               Gamma[1][1] = gamma;          Gamma[1][2] = 0;              Gamma[1][3] = 0;
86442faf41dSJed Brown   Gamma[2][0] = beta3p-beta32-A[2][0];        Gamma[2][1] = beta32-A[2][1]; Gamma[2][2] = gamma;          Gamma[2][3] = 0;
86542faf41dSJed Brown   Gamma[3][0] = beta4p-beta42-beta43-A[3][0]; Gamma[3][1] = beta42-A[3][1]; Gamma[3][2] = beta43-A[3][2]; Gamma[3][3] = gamma;
86642faf41dSJed Brown   b[0] = b1; b[1] = b2; b[2] = b3; b[3] = b4;
86742faf41dSJed Brown 
86842faf41dSJed Brown   /* Construct embedded formula using given e4. We are solving Equation 7.18. */
86942faf41dSJed Brown   bm[3] = b[3] - e4*gamma;                                          /* using definition of E4 */
87042faf41dSJed Brown   bm[2] = (p32 - beta4jbetajp*bm[3]) / (beta32*beta2p);             /* fourth row of 7.18 */
87142faf41dSJed Brown   bm[1] = (one/two - gamma - beta3p*bm[2] - beta4p*bm[3]) / beta2p; /* second row */
87242faf41dSJed Brown   bm[0] = one - bm[1] - bm[2] - bm[3];                              /* first row */
87342faf41dSJed Brown 
87442faf41dSJed Brown   {
87542faf41dSJed Brown     const PetscReal misfit = a2*a2*bm[1] + a3*a3*bm[2] + a4*a4*bm[3] - one/three;
8763c633725SBarry Smith     PetscCheck(PetscAbs(misfit) <= PETSC_SMALL,PETSC_COMM_SELF,PETSC_ERR_SUP,"Assumptions violated, could not construct a third order embedded method");
87742faf41dSJed Brown   }
8789566063dSJacob Faibussowitsch   PetscCall(TSRosWRegister(name,4,4,&A[0][0],&Gamma[0][0],b,bm,0,NULL));
87942faf41dSJed Brown   PetscFunctionReturn(0);
88042faf41dSJed Brown }
88142faf41dSJed Brown 
8821c3436cfSJed Brown /*
8831c3436cfSJed Brown  The step completion formula is
8841c3436cfSJed Brown 
8851c3436cfSJed Brown  x1 = x0 + b^T Y
8861c3436cfSJed Brown 
8871c3436cfSJed Brown  where Y is the multi-vector of stages corrections. This function can be called before or after ts->vec_sol has been
8881c3436cfSJed Brown  updated. Suppose we have a completion formula b and an embedded formula be of different order. We can write
8891c3436cfSJed Brown 
8901c3436cfSJed Brown  x1e = x0 + be^T Y
8911c3436cfSJed Brown      = x1 - b^T Y + be^T Y
8921c3436cfSJed Brown      = x1 + (be - b)^T Y
8931c3436cfSJed Brown 
8941c3436cfSJed Brown  so we can evaluate the method of different order even after the step has been optimistically completed.
8951c3436cfSJed Brown */
896f9c1d6abSBarry Smith static PetscErrorCode TSEvaluateStep_RosW(TS ts,PetscInt order,Vec U,PetscBool *done)
8971c3436cfSJed Brown {
8981c3436cfSJed Brown   TS_RosW        *ros = (TS_RosW*)ts->data;
8991c3436cfSJed Brown   RosWTableau    tab  = ros->tableau;
9001c3436cfSJed Brown   PetscScalar    *w   = ros->work;
9011c3436cfSJed Brown   PetscInt       i;
9021c3436cfSJed Brown 
9031c3436cfSJed Brown   PetscFunctionBegin;
9041c3436cfSJed Brown   if (order == tab->order) {
905108c343cSJed Brown     if (ros->status == TS_STEP_INCOMPLETE) { /* Use standard completion formula */
9069566063dSJacob Faibussowitsch       PetscCall(VecCopy(ts->vec_sol,U));
907de19f811SJed Brown       for (i=0; i<tab->s; i++) w[i] = tab->bt[i];
9089566063dSJacob Faibussowitsch       PetscCall(VecMAXPY(U,tab->s,w,ros->Y));
9099566063dSJacob Faibussowitsch     } else PetscCall(VecCopy(ts->vec_sol,U));
9101c3436cfSJed Brown     if (done) *done = PETSC_TRUE;
9111c3436cfSJed Brown     PetscFunctionReturn(0);
9121c3436cfSJed Brown   } else if (order == tab->order-1) {
9131c3436cfSJed Brown     if (!tab->bembedt) goto unavailable;
914108c343cSJed Brown     if (ros->status == TS_STEP_INCOMPLETE) { /* Use embedded completion formula */
9159566063dSJacob Faibussowitsch       PetscCall(VecCopy(ts->vec_sol,U));
916de19f811SJed Brown       for (i=0; i<tab->s; i++) w[i] = tab->bembedt[i];
9179566063dSJacob Faibussowitsch       PetscCall(VecMAXPY(U,tab->s,w,ros->Y));
918108c343cSJed Brown     } else {                    /* Use rollback-and-recomplete formula (bembedt - bt) */
919108c343cSJed Brown       for (i=0; i<tab->s; i++) w[i] = tab->bembedt[i] - tab->bt[i];
9209566063dSJacob Faibussowitsch       PetscCall(VecCopy(ts->vec_sol,U));
9219566063dSJacob Faibussowitsch       PetscCall(VecMAXPY(U,tab->s,w,ros->Y));
9221c3436cfSJed Brown     }
9231c3436cfSJed Brown     if (done) *done = PETSC_TRUE;
9241c3436cfSJed Brown     PetscFunctionReturn(0);
9251c3436cfSJed Brown   }
9261c3436cfSJed Brown   unavailable:
9271c3436cfSJed Brown   if (done) *done = PETSC_FALSE;
92898921bdaSJacob Faibussowitsch   else SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Rosenbrock-W '%s' of order %D cannot evaluate step at order %D. Consider using -ts_adapt_type none or a different method that has an embedded estimate.",tab->name,tab->order,order);
9291c3436cfSJed Brown   PetscFunctionReturn(0);
9301c3436cfSJed Brown }
9311c3436cfSJed Brown 
932560360afSLisandro Dalcin static PetscErrorCode TSRollBack_RosW(TS ts)
93324655328SShri {
93424655328SShri   TS_RosW        *ros = (TS_RosW*)ts->data;
93524655328SShri 
93624655328SShri   PetscFunctionBegin;
9379566063dSJacob Faibussowitsch   PetscCall(VecCopy(ros->vec_sol_prev,ts->vec_sol));
93824655328SShri   PetscFunctionReturn(0);
93924655328SShri }
94024655328SShri 
941e27a552bSJed Brown static PetscErrorCode TSStep_RosW(TS ts)
942e27a552bSJed Brown {
94361692a83SJed Brown   TS_RosW         *ros = (TS_RosW*)ts->data;
94461692a83SJed Brown   RosWTableau     tab  = ros->tableau;
945e27a552bSJed Brown   const PetscInt  s    = tab->s;
9461c3436cfSJed Brown   const PetscReal *At  = tab->At,*Gamma = tab->Gamma,*ASum = tab->ASum,*GammaInv = tab->GammaInv;
9470feba352SEmil Constantinescu   const PetscReal *GammaExplicitCorr = tab->GammaExplicitCorr;
948c17803e7SJed Brown   const PetscBool *GammaZeroDiag = tab->GammaZeroDiag;
94961692a83SJed Brown   PetscScalar     *w   = ros->work;
9507d4bf2deSEmil Constantinescu   Vec             *Y   = ros->Y,Ydot = ros->Ydot,Zdot = ros->Zdot,Zstage = ros->Zstage;
951e27a552bSJed Brown   SNES            snes;
9521c3436cfSJed Brown   TSAdapt         adapt;
953fecfb714SLisandro Dalcin   PetscInt        i,j,its,lits;
954be5899b3SLisandro Dalcin   PetscInt        rejections = 0;
955b39943a6SLisandro Dalcin   PetscBool       stageok,accept = PETSC_TRUE;
956b39943a6SLisandro Dalcin   PetscReal       next_time_step = ts->time_step;
957f7f07198SBarry Smith   PetscInt        lag;
958e27a552bSJed Brown 
959e27a552bSJed Brown   PetscFunctionBegin;
960b39943a6SLisandro Dalcin   if (!ts->steprollback) {
9619566063dSJacob Faibussowitsch     PetscCall(VecCopy(ts->vec_sol,ros->vec_sol_prev));
962b39943a6SLisandro Dalcin   }
963e27a552bSJed Brown 
964b39943a6SLisandro Dalcin   ros->status = TS_STEP_INCOMPLETE;
965b39943a6SLisandro Dalcin   while (!ts->reason && ros->status != TS_STEP_COMPLETE) {
9661c3436cfSJed Brown     const PetscReal h = ts->time_step;
967e27a552bSJed Brown     for (i=0; i<s; i++) {
9681c3436cfSJed Brown       ros->stage_time = ts->ptime + h*ASum[i];
9699566063dSJacob Faibussowitsch       PetscCall(TSPreStage(ts,ros->stage_time));
970c17803e7SJed Brown       if (GammaZeroDiag[i]) {
971c17803e7SJed Brown         ros->stage_explicit = PETSC_TRUE;
972b296d7d5SJed Brown         ros->scoeff         = 1.;
973c17803e7SJed Brown       } else {
974c17803e7SJed Brown         ros->stage_explicit = PETSC_FALSE;
975b296d7d5SJed Brown         ros->scoeff         = 1./Gamma[i*s+i];
976fd96d5b0SEmil Constantinescu       }
97761692a83SJed Brown 
9789566063dSJacob Faibussowitsch       PetscCall(VecCopy(ts->vec_sol,Zstage));
979de19f811SJed Brown       for (j=0; j<i; j++) w[j] = At[i*s+j];
9809566063dSJacob Faibussowitsch       PetscCall(VecMAXPY(Zstage,i,w,Y));
98161692a83SJed Brown 
98261692a83SJed Brown       for (j=0; j<i; j++) w[j] = 1./h * GammaInv[i*s+j];
9839566063dSJacob Faibussowitsch       PetscCall(VecZeroEntries(Zdot));
9849566063dSJacob Faibussowitsch       PetscCall(VecMAXPY(Zdot,i,w,Y));
98561692a83SJed Brown 
986e27a552bSJed Brown       /* Initial guess taken from last stage */
9879566063dSJacob Faibussowitsch       PetscCall(VecZeroEntries(Y[i]));
98861692a83SJed Brown 
9897d4bf2deSEmil Constantinescu       if (!ros->stage_explicit) {
9909566063dSJacob Faibussowitsch         PetscCall(TSGetSNES(ts,&snes));
99161692a83SJed Brown         if (!ros->recompute_jacobian && !i) {
9929566063dSJacob Faibussowitsch           PetscCall(SNESGetLagJacobian(snes,&lag));
993f7f07198SBarry Smith           if (lag == 1) {  /* use did not set a nontrival lag, so lag over all stages */
9949566063dSJacob Faibussowitsch             PetscCall(SNESSetLagJacobian(snes,-2)); /* Recompute the Jacobian on this solve, but not again for the rest of the stages */
995f7f07198SBarry Smith           }
99661692a83SJed Brown         }
9979566063dSJacob Faibussowitsch         PetscCall(SNESSolve(snes,NULL,Y[i]));
998f7f07198SBarry Smith         if (!ros->recompute_jacobian && i == s-1 && lag == 1) {
9999566063dSJacob Faibussowitsch           PetscCall(SNESSetLagJacobian(snes,lag)); /* Set lag back to 1 so we know user did not set it */
1000f7f07198SBarry Smith         }
10019566063dSJacob Faibussowitsch         PetscCall(SNESGetIterationNumber(snes,&its));
10029566063dSJacob Faibussowitsch         PetscCall(SNESGetLinearSolveIterations(snes,&lits));
10035ef26d82SJed Brown         ts->snes_its += its; ts->ksp_its += lits;
10047d4bf2deSEmil Constantinescu       } else {
10051ce71dffSSatish Balay         Mat J,Jp;
10069566063dSJacob Faibussowitsch         PetscCall(VecZeroEntries(Ydot)); /* Evaluate Y[i]=G(t,Ydot=0,Zstage) */
10079566063dSJacob Faibussowitsch         PetscCall(TSComputeIFunction(ts,ros->stage_time,Zstage,Ydot,Y[i],PETSC_FALSE));
10089566063dSJacob Faibussowitsch         PetscCall(VecScale(Y[i],-1.0));
10099566063dSJacob Faibussowitsch         PetscCall(VecAXPY(Y[i],-1.0,Zdot)); /*Y[i] = F(Zstage)-Zdot[=GammaInv*Y]*/
10100feba352SEmil Constantinescu 
10119566063dSJacob Faibussowitsch         PetscCall(VecZeroEntries(Zstage)); /* Zstage = GammaExplicitCorr[i,j] * Y[j] */
10120feba352SEmil Constantinescu         for (j=0; j<i; j++) w[j] = GammaExplicitCorr[i*s+j];
10139566063dSJacob Faibussowitsch         PetscCall(VecMAXPY(Zstage,i,w,Y));
1014fecfb714SLisandro Dalcin 
1015fecfb714SLisandro Dalcin         /* Y[i] = Y[i] + Jac*Zstage[=Jac*GammaExplicitCorr[i,j] * Y[j]] */
10169566063dSJacob Faibussowitsch         PetscCall(TSGetIJacobian(ts,&J,&Jp,NULL,NULL));
10179566063dSJacob Faibussowitsch         PetscCall(TSComputeIJacobian(ts,ros->stage_time,ts->vec_sol,Ydot,0,J,Jp,PETSC_FALSE));
10189566063dSJacob Faibussowitsch         PetscCall(MatMult(J,Zstage,Zdot));
10199566063dSJacob Faibussowitsch         PetscCall(VecAXPY(Y[i],-1.0,Zdot));
10205ef26d82SJed Brown         ts->ksp_its += 1;
1021fecfb714SLisandro Dalcin 
10229566063dSJacob Faibussowitsch         PetscCall(VecScale(Y[i],h));
10237d4bf2deSEmil Constantinescu       }
10249566063dSJacob Faibussowitsch       PetscCall(TSPostStage(ts,ros->stage_time,i,Y));
10259566063dSJacob Faibussowitsch       PetscCall(TSGetAdapt(ts,&adapt));
10269566063dSJacob Faibussowitsch       PetscCall(TSAdaptCheckStage(adapt,ts,ros->stage_time,Y[i],&stageok));
1027fecfb714SLisandro Dalcin       if (!stageok) goto reject_step;
1028e27a552bSJed Brown     }
1029e27a552bSJed Brown 
1030b39943a6SLisandro Dalcin     ros->status = TS_STEP_INCOMPLETE;
10319566063dSJacob Faibussowitsch     PetscCall(TSEvaluateStep_RosW(ts,tab->order,ts->vec_sol,NULL));
1032b39943a6SLisandro Dalcin     ros->status = TS_STEP_PENDING;
10339566063dSJacob Faibussowitsch     PetscCall(TSGetAdapt(ts,&adapt));
10349566063dSJacob Faibussowitsch     PetscCall(TSAdaptCandidatesClear(adapt));
10359566063dSJacob Faibussowitsch     PetscCall(TSAdaptCandidateAdd(adapt,tab->name,tab->order,1,tab->ccfl,(PetscReal)tab->s,PETSC_TRUE));
10369566063dSJacob Faibussowitsch     PetscCall(TSAdaptChoose(adapt,ts,ts->time_step,NULL,&next_time_step,&accept));
1037b39943a6SLisandro Dalcin     ros->status = accept ? TS_STEP_COMPLETE : TS_STEP_INCOMPLETE;
1038b39943a6SLisandro Dalcin     if (!accept) { /* Roll back the current step */
10399566063dSJacob Faibussowitsch       PetscCall(TSRollBack_RosW(ts));
1040be5899b3SLisandro Dalcin       ts->time_step = next_time_step;
1041be5899b3SLisandro Dalcin       goto reject_step;
1042b39943a6SLisandro Dalcin     }
1043b39943a6SLisandro Dalcin 
1044e27a552bSJed Brown     ts->ptime += ts->time_step;
1045cdbf8f93SLisandro Dalcin     ts->time_step = next_time_step;
10461c3436cfSJed Brown     break;
1047b39943a6SLisandro Dalcin 
1048b39943a6SLisandro Dalcin   reject_step:
1049fecfb714SLisandro Dalcin     ts->reject++; accept = PETSC_FALSE;
1050be5899b3SLisandro Dalcin     if (!ts->reason && ++rejections > ts->max_reject && ts->max_reject >= 0) {
1051b39943a6SLisandro Dalcin       ts->reason = TS_DIVERGED_STEP_REJECTED;
10529566063dSJacob Faibussowitsch       PetscCall(PetscInfo(ts,"Step=%D, step rejections %D greater than current TS allowed, stopping solve\n",ts->steps,rejections));
10531c3436cfSJed Brown     }
10541c3436cfSJed Brown   }
1055e27a552bSJed Brown   PetscFunctionReturn(0);
1056e27a552bSJed Brown }
1057e27a552bSJed Brown 
1058f9c1d6abSBarry Smith static PetscErrorCode TSInterpolate_RosW(TS ts,PetscReal itime,Vec U)
1059e27a552bSJed Brown {
106061692a83SJed Brown   TS_RosW         *ros = (TS_RosW*)ts->data;
1061f4aed992SEmil Constantinescu   PetscInt        s    = ros->tableau->s,pinterp = ros->tableau->pinterp,i,j;
1062f4aed992SEmil Constantinescu   PetscReal       h;
1063f4aed992SEmil Constantinescu   PetscReal       tt,t;
1064f4aed992SEmil Constantinescu   PetscScalar     *bt;
1065f4aed992SEmil Constantinescu   const PetscReal *Bt = ros->tableau->binterpt;
1066f4aed992SEmil Constantinescu   const PetscReal *GammaInv = ros->tableau->GammaInv;
1067f4aed992SEmil Constantinescu   PetscScalar     *w        = ros->work;
1068f4aed992SEmil Constantinescu   Vec             *Y        = ros->Y;
1069e27a552bSJed Brown 
1070e27a552bSJed Brown   PetscFunctionBegin;
10713c633725SBarry Smith   PetscCheck(Bt,PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSRosW %s does not have an interpolation formula",ros->tableau->name);
1072f4aed992SEmil Constantinescu 
1073f4aed992SEmil Constantinescu   switch (ros->status) {
1074f4aed992SEmil Constantinescu   case TS_STEP_INCOMPLETE:
1075f4aed992SEmil Constantinescu   case TS_STEP_PENDING:
1076f4aed992SEmil Constantinescu     h = ts->time_step;
1077f4aed992SEmil Constantinescu     t = (itime - ts->ptime)/h;
1078f4aed992SEmil Constantinescu     break;
1079f4aed992SEmil Constantinescu   case TS_STEP_COMPLETE:
1080be5899b3SLisandro Dalcin     h = ts->ptime - ts->ptime_prev;
1081f4aed992SEmil Constantinescu     t = (itime - ts->ptime)/h + 1; /* In the interval [0,1] */
1082f4aed992SEmil Constantinescu     break;
1083ce94432eSBarry Smith   default: SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_PLIB,"Invalid TSStepStatus");
1084f4aed992SEmil Constantinescu   }
10859566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(s,&bt));
1086f4aed992SEmil Constantinescu   for (i=0; i<s; i++) bt[i] = 0;
1087f4aed992SEmil Constantinescu   for (j=0,tt=t; j<pinterp; j++,tt*=t) {
1088f4aed992SEmil Constantinescu     for (i=0; i<s; i++) {
10893ca35412SEmil Constantinescu       bt[i] += Bt[i*pinterp+j] * tt;
1090f4aed992SEmil Constantinescu     }
1091f4aed992SEmil Constantinescu   }
1092f4aed992SEmil Constantinescu 
1093f4aed992SEmil Constantinescu   /* y(t+tt*h) = y(t) + Sum bt(tt) * GammaInv * Ydot */
1094f9c1d6abSBarry Smith   /* U <- 0*/
10959566063dSJacob Faibussowitsch   PetscCall(VecZeroEntries(U));
1096f9c1d6abSBarry Smith   /* U <- Sum bt_i * GammaInv(i,1:i) * Y(1:i) */
10973ca35412SEmil Constantinescu   for (j=0; j<s; j++) w[j] = 0;
10983ca35412SEmil Constantinescu   for (j=0; j<s; j++) {
10993ca35412SEmil Constantinescu     for (i=j; i<s; i++) {
11003ca35412SEmil Constantinescu       w[j] +=  bt[i]*GammaInv[i*s+j];
1101f4aed992SEmil Constantinescu     }
11023ca35412SEmil Constantinescu   }
11039566063dSJacob Faibussowitsch   PetscCall(VecMAXPY(U,i,w,Y));
1104be5899b3SLisandro Dalcin   /* U <- y(t) + U */
11059566063dSJacob Faibussowitsch   PetscCall(VecAXPY(U,1,ros->vec_sol_prev));
1106f4aed992SEmil Constantinescu 
11079566063dSJacob Faibussowitsch   PetscCall(PetscFree(bt));
1108e27a552bSJed Brown   PetscFunctionReturn(0);
1109e27a552bSJed Brown }
1110e27a552bSJed Brown 
1111e27a552bSJed Brown /*------------------------------------------------------------*/
1112b39943a6SLisandro Dalcin 
1113b39943a6SLisandro Dalcin static PetscErrorCode TSRosWTableauReset(TS ts)
1114b39943a6SLisandro Dalcin {
1115b39943a6SLisandro Dalcin   TS_RosW        *ros = (TS_RosW*)ts->data;
1116b39943a6SLisandro Dalcin   RosWTableau    tab  = ros->tableau;
1117b39943a6SLisandro Dalcin 
1118b39943a6SLisandro Dalcin   PetscFunctionBegin;
1119b39943a6SLisandro Dalcin   if (!tab) PetscFunctionReturn(0);
11209566063dSJacob Faibussowitsch   PetscCall(VecDestroyVecs(tab->s,&ros->Y));
11219566063dSJacob Faibussowitsch   PetscCall(PetscFree(ros->work));
1122b39943a6SLisandro Dalcin   PetscFunctionReturn(0);
1123b39943a6SLisandro Dalcin }
1124b39943a6SLisandro Dalcin 
1125e27a552bSJed Brown static PetscErrorCode TSReset_RosW(TS ts)
1126e27a552bSJed Brown {
112761692a83SJed Brown   TS_RosW        *ros = (TS_RosW*)ts->data;
1128e27a552bSJed Brown 
1129e27a552bSJed Brown   PetscFunctionBegin;
11309566063dSJacob Faibussowitsch   PetscCall(TSRosWTableauReset(ts));
11319566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&ros->Ydot));
11329566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&ros->Ystage));
11339566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&ros->Zdot));
11349566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&ros->Zstage));
11359566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&ros->vec_sol_prev));
1136e27a552bSJed Brown   PetscFunctionReturn(0);
1137e27a552bSJed Brown }
1138e27a552bSJed Brown 
1139d5e6173cSPeter Brune static PetscErrorCode TSRosWGetVecs(TS ts,DM dm,Vec *Ydot,Vec *Zdot,Vec *Ystage,Vec *Zstage)
1140d5e6173cSPeter Brune {
1141d5e6173cSPeter Brune   TS_RosW        *rw = (TS_RosW*)ts->data;
1142d5e6173cSPeter Brune 
1143d5e6173cSPeter Brune   PetscFunctionBegin;
1144d5e6173cSPeter Brune   if (Ydot) {
1145d5e6173cSPeter Brune     if (dm && dm != ts->dm) {
11469566063dSJacob Faibussowitsch       PetscCall(DMGetNamedGlobalVector(dm,"TSRosW_Ydot",Ydot));
1147d5e6173cSPeter Brune     } else *Ydot = rw->Ydot;
1148d5e6173cSPeter Brune   }
1149d5e6173cSPeter Brune   if (Zdot) {
1150d5e6173cSPeter Brune     if (dm && dm != ts->dm) {
11519566063dSJacob Faibussowitsch       PetscCall(DMGetNamedGlobalVector(dm,"TSRosW_Zdot",Zdot));
1152d5e6173cSPeter Brune     } else *Zdot = rw->Zdot;
1153d5e6173cSPeter Brune   }
1154d5e6173cSPeter Brune   if (Ystage) {
1155d5e6173cSPeter Brune     if (dm && dm != ts->dm) {
11569566063dSJacob Faibussowitsch       PetscCall(DMGetNamedGlobalVector(dm,"TSRosW_Ystage",Ystage));
1157d5e6173cSPeter Brune     } else *Ystage = rw->Ystage;
1158d5e6173cSPeter Brune   }
1159d5e6173cSPeter Brune   if (Zstage) {
1160d5e6173cSPeter Brune     if (dm && dm != ts->dm) {
11619566063dSJacob Faibussowitsch       PetscCall(DMGetNamedGlobalVector(dm,"TSRosW_Zstage",Zstage));
1162d5e6173cSPeter Brune     } else *Zstage = rw->Zstage;
1163d5e6173cSPeter Brune   }
1164d5e6173cSPeter Brune   PetscFunctionReturn(0);
1165d5e6173cSPeter Brune }
1166d5e6173cSPeter Brune 
1167d5e6173cSPeter Brune static PetscErrorCode TSRosWRestoreVecs(TS ts,DM dm,Vec *Ydot,Vec *Zdot, Vec *Ystage, Vec *Zstage)
1168d5e6173cSPeter Brune {
1169d5e6173cSPeter Brune   PetscFunctionBegin;
1170d5e6173cSPeter Brune   if (Ydot) {
1171d5e6173cSPeter Brune     if (dm && dm != ts->dm) {
11729566063dSJacob Faibussowitsch       PetscCall(DMRestoreNamedGlobalVector(dm,"TSRosW_Ydot",Ydot));
1173d5e6173cSPeter Brune     }
1174d5e6173cSPeter Brune   }
1175d5e6173cSPeter Brune   if (Zdot) {
1176d5e6173cSPeter Brune     if (dm && dm != ts->dm) {
11779566063dSJacob Faibussowitsch       PetscCall(DMRestoreNamedGlobalVector(dm,"TSRosW_Zdot",Zdot));
1178d5e6173cSPeter Brune     }
1179d5e6173cSPeter Brune   }
1180d5e6173cSPeter Brune   if (Ystage) {
1181d5e6173cSPeter Brune     if (dm && dm != ts->dm) {
11829566063dSJacob Faibussowitsch       PetscCall(DMRestoreNamedGlobalVector(dm,"TSRosW_Ystage",Ystage));
1183d5e6173cSPeter Brune     }
1184d5e6173cSPeter Brune   }
1185d5e6173cSPeter Brune   if (Zstage) {
1186d5e6173cSPeter Brune     if (dm && dm != ts->dm) {
11879566063dSJacob Faibussowitsch       PetscCall(DMRestoreNamedGlobalVector(dm,"TSRosW_Zstage",Zstage));
1188d5e6173cSPeter Brune     }
1189d5e6173cSPeter Brune   }
1190d5e6173cSPeter Brune   PetscFunctionReturn(0);
1191d5e6173cSPeter Brune }
1192d5e6173cSPeter Brune 
1193d5e6173cSPeter Brune static PetscErrorCode DMCoarsenHook_TSRosW(DM fine,DM coarse,void *ctx)
1194d5e6173cSPeter Brune {
1195d5e6173cSPeter Brune   PetscFunctionBegin;
1196d5e6173cSPeter Brune   PetscFunctionReturn(0);
1197d5e6173cSPeter Brune }
1198d5e6173cSPeter Brune 
1199d5e6173cSPeter Brune static PetscErrorCode DMRestrictHook_TSRosW(DM fine,Mat restrct,Vec rscale,Mat inject,DM coarse,void *ctx)
1200d5e6173cSPeter Brune {
1201d5e6173cSPeter Brune   TS             ts = (TS)ctx;
1202d5e6173cSPeter Brune   Vec            Ydot,Zdot,Ystage,Zstage;
1203d5e6173cSPeter Brune   Vec            Ydotc,Zdotc,Ystagec,Zstagec;
1204d5e6173cSPeter Brune 
1205d5e6173cSPeter Brune   PetscFunctionBegin;
12069566063dSJacob Faibussowitsch   PetscCall(TSRosWGetVecs(ts,fine,&Ydot,&Ystage,&Zdot,&Zstage));
12079566063dSJacob Faibussowitsch   PetscCall(TSRosWGetVecs(ts,coarse,&Ydotc,&Ystagec,&Zdotc,&Zstagec));
12089566063dSJacob Faibussowitsch   PetscCall(MatRestrict(restrct,Ydot,Ydotc));
12099566063dSJacob Faibussowitsch   PetscCall(VecPointwiseMult(Ydotc,rscale,Ydotc));
12109566063dSJacob Faibussowitsch   PetscCall(MatRestrict(restrct,Ystage,Ystagec));
12119566063dSJacob Faibussowitsch   PetscCall(VecPointwiseMult(Ystagec,rscale,Ystagec));
12129566063dSJacob Faibussowitsch   PetscCall(MatRestrict(restrct,Zdot,Zdotc));
12139566063dSJacob Faibussowitsch   PetscCall(VecPointwiseMult(Zdotc,rscale,Zdotc));
12149566063dSJacob Faibussowitsch   PetscCall(MatRestrict(restrct,Zstage,Zstagec));
12159566063dSJacob Faibussowitsch   PetscCall(VecPointwiseMult(Zstagec,rscale,Zstagec));
12169566063dSJacob Faibussowitsch   PetscCall(TSRosWRestoreVecs(ts,fine,&Ydot,&Ystage,&Zdot,&Zstage));
12179566063dSJacob Faibussowitsch   PetscCall(TSRosWRestoreVecs(ts,coarse,&Ydotc,&Ystagec,&Zdotc,&Zstagec));
1218d5e6173cSPeter Brune   PetscFunctionReturn(0);
1219d5e6173cSPeter Brune }
1220d5e6173cSPeter Brune 
1221258e1594SPeter Brune static PetscErrorCode DMSubDomainHook_TSRosW(DM fine,DM coarse,void *ctx)
1222258e1594SPeter Brune {
1223258e1594SPeter Brune   PetscFunctionBegin;
1224258e1594SPeter Brune   PetscFunctionReturn(0);
1225258e1594SPeter Brune }
1226258e1594SPeter Brune 
1227258e1594SPeter Brune static PetscErrorCode DMSubDomainRestrictHook_TSRosW(DM dm,VecScatter gscat,VecScatter lscat,DM subdm,void *ctx)
1228258e1594SPeter Brune {
1229258e1594SPeter Brune   TS             ts = (TS)ctx;
1230258e1594SPeter Brune   Vec            Ydot,Zdot,Ystage,Zstage;
1231258e1594SPeter Brune   Vec            Ydots,Zdots,Ystages,Zstages;
1232258e1594SPeter Brune 
1233258e1594SPeter Brune   PetscFunctionBegin;
12349566063dSJacob Faibussowitsch   PetscCall(TSRosWGetVecs(ts,dm,&Ydot,&Ystage,&Zdot,&Zstage));
12359566063dSJacob Faibussowitsch   PetscCall(TSRosWGetVecs(ts,subdm,&Ydots,&Ystages,&Zdots,&Zstages));
1236258e1594SPeter Brune 
12379566063dSJacob Faibussowitsch   PetscCall(VecScatterBegin(gscat,Ydot,Ydots,INSERT_VALUES,SCATTER_FORWARD));
12389566063dSJacob Faibussowitsch   PetscCall(VecScatterEnd(gscat,Ydot,Ydots,INSERT_VALUES,SCATTER_FORWARD));
1239258e1594SPeter Brune 
12409566063dSJacob Faibussowitsch   PetscCall(VecScatterBegin(gscat,Ystage,Ystages,INSERT_VALUES,SCATTER_FORWARD));
12419566063dSJacob Faibussowitsch   PetscCall(VecScatterEnd(gscat,Ystage,Ystages,INSERT_VALUES,SCATTER_FORWARD));
1242258e1594SPeter Brune 
12439566063dSJacob Faibussowitsch   PetscCall(VecScatterBegin(gscat,Zdot,Zdots,INSERT_VALUES,SCATTER_FORWARD));
12449566063dSJacob Faibussowitsch   PetscCall(VecScatterEnd(gscat,Zdot,Zdots,INSERT_VALUES,SCATTER_FORWARD));
1245258e1594SPeter Brune 
12469566063dSJacob Faibussowitsch   PetscCall(VecScatterBegin(gscat,Zstage,Zstages,INSERT_VALUES,SCATTER_FORWARD));
12479566063dSJacob Faibussowitsch   PetscCall(VecScatterEnd(gscat,Zstage,Zstages,INSERT_VALUES,SCATTER_FORWARD));
1248258e1594SPeter Brune 
12499566063dSJacob Faibussowitsch   PetscCall(TSRosWRestoreVecs(ts,dm,&Ydot,&Ystage,&Zdot,&Zstage));
12509566063dSJacob Faibussowitsch   PetscCall(TSRosWRestoreVecs(ts,subdm,&Ydots,&Ystages,&Zdots,&Zstages));
1251258e1594SPeter Brune   PetscFunctionReturn(0);
1252258e1594SPeter Brune }
1253258e1594SPeter Brune 
1254e27a552bSJed Brown /*
1255e27a552bSJed Brown   This defines the nonlinear equation that is to be solved with SNES
1256e27a552bSJed Brown   G(U) = F[t0+Theta*dt, U, (U-U0)*shift] = 0
1257e27a552bSJed Brown */
1258f9c1d6abSBarry Smith static PetscErrorCode SNESTSFormFunction_RosW(SNES snes,Vec U,Vec F,TS ts)
1259e27a552bSJed Brown {
126061692a83SJed Brown   TS_RosW        *ros = (TS_RosW*)ts->data;
1261d5e6173cSPeter Brune   Vec            Ydot,Zdot,Ystage,Zstage;
1262b296d7d5SJed Brown   PetscReal      shift = ros->scoeff / ts->time_step;
1263d5e6173cSPeter Brune   DM             dm,dmsave;
1264e27a552bSJed Brown 
1265e27a552bSJed Brown   PetscFunctionBegin;
12669566063dSJacob Faibussowitsch   PetscCall(SNESGetDM(snes,&dm));
12679566063dSJacob Faibussowitsch   PetscCall(TSRosWGetVecs(ts,dm,&Ydot,&Zdot,&Ystage,&Zstage));
12689566063dSJacob Faibussowitsch   PetscCall(VecWAXPY(Ydot,shift,U,Zdot));    /* Ydot = shift*U + Zdot */
12699566063dSJacob Faibussowitsch   PetscCall(VecWAXPY(Ystage,1.0,U,Zstage));  /* Ystage = U + Zstage */
1270d5e6173cSPeter Brune   dmsave = ts->dm;
1271d5e6173cSPeter Brune   ts->dm = dm;
12729566063dSJacob Faibussowitsch   PetscCall(TSComputeIFunction(ts,ros->stage_time,Ystage,Ydot,F,PETSC_FALSE));
1273d5e6173cSPeter Brune   ts->dm = dmsave;
12749566063dSJacob Faibussowitsch   PetscCall(TSRosWRestoreVecs(ts,dm,&Ydot,&Zdot,&Ystage,&Zstage));
1275e27a552bSJed Brown   PetscFunctionReturn(0);
1276e27a552bSJed Brown }
1277e27a552bSJed Brown 
1278d1e9a80fSBarry Smith static PetscErrorCode SNESTSFormJacobian_RosW(SNES snes,Vec U,Mat A,Mat B,TS ts)
1279e27a552bSJed Brown {
128061692a83SJed Brown   TS_RosW        *ros = (TS_RosW*)ts->data;
1281d5e6173cSPeter Brune   Vec            Ydot,Zdot,Ystage,Zstage;
1282b296d7d5SJed Brown   PetscReal      shift = ros->scoeff / ts->time_step;
1283d5e6173cSPeter Brune   DM             dm,dmsave;
1284e27a552bSJed Brown 
1285e27a552bSJed Brown   PetscFunctionBegin;
128661692a83SJed Brown   /* ros->Ydot and ros->Ystage have already been computed in SNESTSFormFunction_RosW (SNES guarantees this) */
12879566063dSJacob Faibussowitsch   PetscCall(SNESGetDM(snes,&dm));
12889566063dSJacob Faibussowitsch   PetscCall(TSRosWGetVecs(ts,dm,&Ydot,&Zdot,&Ystage,&Zstage));
1289d5e6173cSPeter Brune   dmsave = ts->dm;
1290d5e6173cSPeter Brune   ts->dm = dm;
12919566063dSJacob Faibussowitsch   PetscCall(TSComputeIJacobian(ts,ros->stage_time,Ystage,Ydot,shift,A,B,PETSC_TRUE));
1292d5e6173cSPeter Brune   ts->dm = dmsave;
12939566063dSJacob Faibussowitsch   PetscCall(TSRosWRestoreVecs(ts,dm,&Ydot,&Zdot,&Ystage,&Zstage));
1294e27a552bSJed Brown   PetscFunctionReturn(0);
1295e27a552bSJed Brown }
1296e27a552bSJed Brown 
1297b39943a6SLisandro Dalcin static PetscErrorCode TSRosWTableauSetUp(TS ts)
1298b39943a6SLisandro Dalcin {
1299b39943a6SLisandro Dalcin   TS_RosW        *ros = (TS_RosW*)ts->data;
1300b39943a6SLisandro Dalcin   RosWTableau    tab  = ros->tableau;
1301b39943a6SLisandro Dalcin 
1302b39943a6SLisandro Dalcin   PetscFunctionBegin;
13039566063dSJacob Faibussowitsch   PetscCall(VecDuplicateVecs(ts->vec_sol,tab->s,&ros->Y));
13049566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(tab->s,&ros->work));
1305b39943a6SLisandro Dalcin   PetscFunctionReturn(0);
1306b39943a6SLisandro Dalcin }
1307b39943a6SLisandro Dalcin 
1308e27a552bSJed Brown static PetscErrorCode TSSetUp_RosW(TS ts)
1309e27a552bSJed Brown {
131061692a83SJed Brown   TS_RosW        *ros = (TS_RosW*)ts->data;
1311d5e6173cSPeter Brune   DM             dm;
1312b39943a6SLisandro Dalcin   SNES           snes;
1313a3ab5968SHong Zhang   TSRHSJacobian  rhsjacobian;
1314e27a552bSJed Brown 
1315e27a552bSJed Brown   PetscFunctionBegin;
13169566063dSJacob Faibussowitsch   PetscCall(TSRosWTableauSetUp(ts));
13179566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(ts->vec_sol,&ros->Ydot));
13189566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(ts->vec_sol,&ros->Ystage));
13199566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(ts->vec_sol,&ros->Zdot));
13209566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(ts->vec_sol,&ros->Zstage));
13219566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(ts->vec_sol,&ros->vec_sol_prev));
13229566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts,&dm));
13239566063dSJacob Faibussowitsch   PetscCall(DMCoarsenHookAdd(dm,DMCoarsenHook_TSRosW,DMRestrictHook_TSRosW,ts));
13249566063dSJacob Faibussowitsch   PetscCall(DMSubDomainHookAdd(dm,DMSubDomainHook_TSRosW,DMSubDomainRestrictHook_TSRosW,ts));
1325b39943a6SLisandro Dalcin   /* Rosenbrock methods are linearly implicit, so set that unless the user has specifically asked for something else */
13269566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts,&snes));
1327b39943a6SLisandro Dalcin   if (!((PetscObject)snes)->type_name) {
13289566063dSJacob Faibussowitsch     PetscCall(SNESSetType(snes,SNESKSPONLY));
1329b39943a6SLisandro Dalcin   }
13309566063dSJacob Faibussowitsch   PetscCall(DMTSGetRHSJacobian(dm,&rhsjacobian,NULL));
1331a3ab5968SHong Zhang   if (rhsjacobian == TSComputeRHSJacobianConstant) {
1332a3ab5968SHong Zhang     Mat Amat,Pmat;
1333a3ab5968SHong Zhang 
1334a3ab5968SHong Zhang     /* Set the SNES matrix to be different from the RHS matrix because there is no way to reconstruct shift*M-J */
13359566063dSJacob Faibussowitsch     PetscCall(SNESGetJacobian(snes,&Amat,&Pmat,NULL,NULL));
1336a3ab5968SHong Zhang     if (Amat && Amat == ts->Arhs) {
1337a3ab5968SHong Zhang       if (Amat == Pmat) {
13389566063dSJacob Faibussowitsch         PetscCall(MatDuplicate(ts->Arhs,MAT_COPY_VALUES,&Amat));
13399566063dSJacob Faibussowitsch         PetscCall(SNESSetJacobian(snes,Amat,Amat,NULL,NULL));
1340a3ab5968SHong Zhang       } else {
13419566063dSJacob Faibussowitsch         PetscCall(MatDuplicate(ts->Arhs,MAT_COPY_VALUES,&Amat));
13429566063dSJacob Faibussowitsch         PetscCall(SNESSetJacobian(snes,Amat,NULL,NULL,NULL));
1343a3ab5968SHong Zhang         if (Pmat && Pmat == ts->Brhs) {
13449566063dSJacob Faibussowitsch           PetscCall(MatDuplicate(ts->Brhs,MAT_COPY_VALUES,&Pmat));
13459566063dSJacob Faibussowitsch           PetscCall(SNESSetJacobian(snes,NULL,Pmat,NULL,NULL));
13469566063dSJacob Faibussowitsch           PetscCall(MatDestroy(&Pmat));
1347a3ab5968SHong Zhang         }
1348a3ab5968SHong Zhang       }
13499566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&Amat));
1350a3ab5968SHong Zhang     }
1351a3ab5968SHong Zhang   }
1352e27a552bSJed Brown   PetscFunctionReturn(0);
1353e27a552bSJed Brown }
1354e27a552bSJed Brown /*------------------------------------------------------------*/
1355e27a552bSJed Brown 
13564416b707SBarry Smith static PetscErrorCode TSSetFromOptions_RosW(PetscOptionItems *PetscOptionsObject,TS ts)
1357e27a552bSJed Brown {
135861692a83SJed Brown   TS_RosW        *ros = (TS_RosW*)ts->data;
1359b39943a6SLisandro Dalcin   SNES           snes;
1360e27a552bSJed Brown 
1361e27a552bSJed Brown   PetscFunctionBegin;
13629566063dSJacob Faibussowitsch   PetscCall(PetscOptionsHead(PetscOptionsObject,"RosW ODE solver options"));
1363e27a552bSJed Brown   {
136461692a83SJed Brown     RosWTableauLink link;
1365e27a552bSJed Brown     PetscInt        count,choice;
1366e27a552bSJed Brown     PetscBool       flg;
1367e27a552bSJed Brown     const char      **namelist;
136861692a83SJed Brown 
136961692a83SJed Brown     for (link=RosWTableauList,count=0; link; link=link->next,count++) ;
13709566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(count,(char***)&namelist));
137161692a83SJed Brown     for (link=RosWTableauList,count=0; link; link=link->next,count++) namelist[count] = link->tab.name;
13729566063dSJacob Faibussowitsch     PetscCall(PetscOptionsEList("-ts_rosw_type","Family of Rosenbrock-W method","TSRosWSetType",(const char*const*)namelist,count,ros->tableau->name,&choice,&flg));
13739566063dSJacob Faibussowitsch     if (flg) PetscCall(TSRosWSetType(ts,namelist[choice]));
13749566063dSJacob Faibussowitsch     PetscCall(PetscFree(namelist));
137561692a83SJed Brown 
13769566063dSJacob Faibussowitsch     PetscCall(PetscOptionsBool("-ts_rosw_recompute_jacobian","Recompute the Jacobian at each stage","TSRosWSetRecomputeJacobian",ros->recompute_jacobian,&ros->recompute_jacobian,NULL));
1377b39943a6SLisandro Dalcin   }
13789566063dSJacob Faibussowitsch   PetscCall(PetscOptionsTail());
137961692a83SJed Brown   /* Rosenbrock methods are linearly implicit, so set that unless the user has specifically asked for something else */
13809566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts,&snes));
138161692a83SJed Brown   if (!((PetscObject)snes)->type_name) {
13829566063dSJacob Faibussowitsch     PetscCall(SNESSetType(snes,SNESKSPONLY));
138361692a83SJed Brown   }
1384e27a552bSJed Brown   PetscFunctionReturn(0);
1385e27a552bSJed Brown }
1386e27a552bSJed Brown 
1387e27a552bSJed Brown static PetscErrorCode TSView_RosW(TS ts,PetscViewer viewer)
1388e27a552bSJed Brown {
138961692a83SJed Brown   TS_RosW        *ros = (TS_RosW*)ts->data;
1390e27a552bSJed Brown   PetscBool      iascii;
1391e27a552bSJed Brown 
1392e27a552bSJed Brown   PetscFunctionBegin;
13939566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
1394e27a552bSJed Brown   if (iascii) {
13959c334d8fSLisandro Dalcin     RosWTableau tab  = ros->tableau;
139619fd82e9SBarry Smith     TSRosWType  rostype;
13979c334d8fSLisandro Dalcin     char        buf[512];
1398e408995aSJed Brown     PetscInt    i;
1399e408995aSJed Brown     PetscReal   abscissa[512];
14009566063dSJacob Faibussowitsch     PetscCall(TSRosWGetType(ts,&rostype));
14019566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"  Rosenbrock-W %s\n",rostype));
14029566063dSJacob Faibussowitsch     PetscCall(PetscFormatRealArray(buf,sizeof(buf),"% 8.6f",tab->s,tab->ASum));
14039566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"  Abscissa of A       = %s\n",buf));
1404e408995aSJed Brown     for (i=0; i<tab->s; i++) abscissa[i] = tab->ASum[i] + tab->Gamma[i];
14059566063dSJacob Faibussowitsch     PetscCall(PetscFormatRealArray(buf,sizeof(buf),"% 8.6f",tab->s,abscissa));
14069566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"  Abscissa of A+Gamma = %s\n",buf));
1407e27a552bSJed Brown   }
1408e27a552bSJed Brown   PetscFunctionReturn(0);
1409e27a552bSJed Brown }
1410e27a552bSJed Brown 
14119200755eSBarry Smith static PetscErrorCode TSLoad_RosW(TS ts,PetscViewer viewer)
14129200755eSBarry Smith {
14139200755eSBarry Smith   SNES           snes;
14149c334d8fSLisandro Dalcin   TSAdapt        adapt;
14159200755eSBarry Smith 
14169200755eSBarry Smith   PetscFunctionBegin;
14179566063dSJacob Faibussowitsch   PetscCall(TSGetAdapt(ts,&adapt));
14189566063dSJacob Faibussowitsch   PetscCall(TSAdaptLoad(adapt,viewer));
14199566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts,&snes));
14209566063dSJacob Faibussowitsch   PetscCall(SNESLoad(snes,viewer));
14219200755eSBarry Smith   /* function and Jacobian context for SNES when used with TS is always ts object */
14229566063dSJacob Faibussowitsch   PetscCall(SNESSetFunction(snes,NULL,NULL,ts));
14239566063dSJacob Faibussowitsch   PetscCall(SNESSetJacobian(snes,NULL,NULL,NULL,ts));
14249200755eSBarry Smith   PetscFunctionReturn(0);
14259200755eSBarry Smith }
14269200755eSBarry Smith 
1427e27a552bSJed Brown /*@C
142861692a83SJed Brown   TSRosWSetType - Set the type of Rosenbrock-W scheme
1429e27a552bSJed Brown 
1430e27a552bSJed Brown   Logically collective
1431e27a552bSJed Brown 
1432d8d19677SJose E. Roman   Input Parameters:
1433e27a552bSJed Brown +  ts - timestepping context
1434b92453a8SLisandro Dalcin -  roswtype - type of Rosenbrock-W scheme
1435e27a552bSJed Brown 
1436020d8f30SJed Brown   Level: beginner
1437e27a552bSJed Brown 
1438020d8f30SJed Brown .seealso: TSRosWGetType(), TSROSW, TSROSW2M, TSROSW2P, TSROSWRA3PW, TSROSWRA34PW2, TSROSWRODAS3, TSROSWSANDU3, TSROSWASSP3P3S1C, TSROSWLASSP3P4S2C, TSROSWLLSSP3P4S2C, TSROSWARK3
1439e27a552bSJed Brown @*/
1440b92453a8SLisandro Dalcin PetscErrorCode TSRosWSetType(TS ts,TSRosWType roswtype)
1441e27a552bSJed Brown {
1442e27a552bSJed Brown   PetscFunctionBegin;
1443e27a552bSJed Brown   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1444b92453a8SLisandro Dalcin   PetscValidCharPointer(roswtype,2);
1445*cac4c232SBarry Smith   PetscTryMethod(ts,"TSRosWSetType_C",(TS,TSRosWType),(ts,roswtype));
1446e27a552bSJed Brown   PetscFunctionReturn(0);
1447e27a552bSJed Brown }
1448e27a552bSJed Brown 
1449e27a552bSJed Brown /*@C
145061692a83SJed Brown   TSRosWGetType - Get the type of Rosenbrock-W scheme
1451e27a552bSJed Brown 
1452e27a552bSJed Brown   Logically collective
1453e27a552bSJed Brown 
1454e27a552bSJed Brown   Input Parameter:
1455e27a552bSJed Brown .  ts - timestepping context
1456e27a552bSJed Brown 
1457e27a552bSJed Brown   Output Parameter:
145861692a83SJed Brown .  rostype - type of Rosenbrock-W scheme
1459e27a552bSJed Brown 
1460e27a552bSJed Brown   Level: intermediate
1461e27a552bSJed Brown 
1462e27a552bSJed Brown .seealso: TSRosWGetType()
1463e27a552bSJed Brown @*/
146419fd82e9SBarry Smith PetscErrorCode TSRosWGetType(TS ts,TSRosWType *rostype)
1465e27a552bSJed Brown {
1466e27a552bSJed Brown   PetscFunctionBegin;
1467e27a552bSJed Brown   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1468*cac4c232SBarry Smith   PetscUseMethod(ts,"TSRosWGetType_C",(TS,TSRosWType*),(ts,rostype));
1469e27a552bSJed Brown   PetscFunctionReturn(0);
1470e27a552bSJed Brown }
1471e27a552bSJed Brown 
1472e27a552bSJed Brown /*@C
147361692a83SJed Brown   TSRosWSetRecomputeJacobian - Set whether to recompute the Jacobian at each stage. The default is to update the Jacobian once per step.
1474e27a552bSJed Brown 
1475e27a552bSJed Brown   Logically collective
1476e27a552bSJed Brown 
1477d8d19677SJose E. Roman   Input Parameters:
1478e27a552bSJed Brown +  ts - timestepping context
147961692a83SJed Brown -  flg - PETSC_TRUE to recompute the Jacobian at each stage
1480e27a552bSJed Brown 
1481e27a552bSJed Brown   Level: intermediate
1482e27a552bSJed Brown 
1483e27a552bSJed Brown .seealso: TSRosWGetType()
1484e27a552bSJed Brown @*/
148561692a83SJed Brown PetscErrorCode TSRosWSetRecomputeJacobian(TS ts,PetscBool flg)
1486e27a552bSJed Brown {
1487e27a552bSJed Brown   PetscFunctionBegin;
1488e27a552bSJed Brown   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1489*cac4c232SBarry Smith   PetscTryMethod(ts,"TSRosWSetRecomputeJacobian_C",(TS,PetscBool),(ts,flg));
1490e27a552bSJed Brown   PetscFunctionReturn(0);
1491e27a552bSJed Brown }
1492e27a552bSJed Brown 
1493560360afSLisandro Dalcin static PetscErrorCode  TSRosWGetType_RosW(TS ts,TSRosWType *rostype)
1494e27a552bSJed Brown {
149561692a83SJed Brown   TS_RosW        *ros = (TS_RosW*)ts->data;
1496e27a552bSJed Brown 
1497e27a552bSJed Brown   PetscFunctionBegin;
149861692a83SJed Brown   *rostype = ros->tableau->name;
1499e27a552bSJed Brown   PetscFunctionReturn(0);
1500e27a552bSJed Brown }
1501ef20d060SBarry Smith 
1502560360afSLisandro Dalcin static PetscErrorCode  TSRosWSetType_RosW(TS ts,TSRosWType rostype)
1503e27a552bSJed Brown {
150461692a83SJed Brown   TS_RosW         *ros = (TS_RosW*)ts->data;
1505e27a552bSJed Brown   PetscBool       match;
150661692a83SJed Brown   RosWTableauLink link;
1507e27a552bSJed Brown 
1508e27a552bSJed Brown   PetscFunctionBegin;
150961692a83SJed Brown   if (ros->tableau) {
15109566063dSJacob Faibussowitsch     PetscCall(PetscStrcmp(ros->tableau->name,rostype,&match));
1511e27a552bSJed Brown     if (match) PetscFunctionReturn(0);
1512e27a552bSJed Brown   }
151361692a83SJed Brown   for (link = RosWTableauList; link; link=link->next) {
15149566063dSJacob Faibussowitsch     PetscCall(PetscStrcmp(link->tab.name,rostype,&match));
1515e27a552bSJed Brown     if (match) {
15169566063dSJacob Faibussowitsch       if (ts->setupcalled) PetscCall(TSRosWTableauReset(ts));
151761692a83SJed Brown       ros->tableau = &link->tab;
15189566063dSJacob Faibussowitsch       if (ts->setupcalled) PetscCall(TSRosWTableauSetUp(ts));
15192ffb9264SLisandro Dalcin       ts->default_adapt_type = ros->tableau->bembed ? TSADAPTBASIC : TSADAPTNONE;
1520e27a552bSJed Brown       PetscFunctionReturn(0);
1521e27a552bSJed Brown     }
1522e27a552bSJed Brown   }
152398921bdaSJacob Faibussowitsch   SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_UNKNOWN_TYPE,"Could not find '%s'",rostype);
1524e27a552bSJed Brown }
152561692a83SJed Brown 
1526560360afSLisandro Dalcin static PetscErrorCode  TSRosWSetRecomputeJacobian_RosW(TS ts,PetscBool flg)
1527e27a552bSJed Brown {
152861692a83SJed Brown   TS_RosW *ros = (TS_RosW*)ts->data;
1529e27a552bSJed Brown 
1530e27a552bSJed Brown   PetscFunctionBegin;
153161692a83SJed Brown   ros->recompute_jacobian = flg;
1532e27a552bSJed Brown   PetscFunctionReturn(0);
1533e27a552bSJed Brown }
1534e27a552bSJed Brown 
1535b3a6b972SJed Brown static PetscErrorCode TSDestroy_RosW(TS ts)
1536b3a6b972SJed Brown {
1537b3a6b972SJed Brown   PetscFunctionBegin;
15389566063dSJacob Faibussowitsch   PetscCall(TSReset_RosW(ts));
1539b3a6b972SJed Brown   if (ts->dm) {
15409566063dSJacob Faibussowitsch     PetscCall(DMCoarsenHookRemove(ts->dm,DMCoarsenHook_TSRosW,DMRestrictHook_TSRosW,ts));
15419566063dSJacob Faibussowitsch     PetscCall(DMSubDomainHookRemove(ts->dm,DMSubDomainHook_TSRosW,DMSubDomainRestrictHook_TSRosW,ts));
1542b3a6b972SJed Brown   }
15439566063dSJacob Faibussowitsch   PetscCall(PetscFree(ts->data));
15449566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)ts,"TSRosWGetType_C",NULL));
15459566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)ts,"TSRosWSetType_C",NULL));
15469566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)ts,"TSRosWSetRecomputeJacobian_C",NULL));
1547b3a6b972SJed Brown   PetscFunctionReturn(0);
1548b3a6b972SJed Brown }
1549d5e6173cSPeter Brune 
1550e27a552bSJed Brown /* ------------------------------------------------------------ */
1551e27a552bSJed Brown /*MC
1552020d8f30SJed Brown       TSROSW - ODE solver using Rosenbrock-W schemes
1553e27a552bSJed Brown 
1554e27a552bSJed Brown   These methods are intended for problems with well-separated time scales, especially when a slow scale is strongly
1555e27a552bSJed Brown   nonlinear such that it is expensive to solve with a fully implicit method. The user should provide the stiff part
1556e27a552bSJed Brown   of the equation using TSSetIFunction() and the non-stiff part with TSSetRHSFunction().
1557e27a552bSJed Brown 
1558e27a552bSJed Brown   Notes:
155961692a83SJed Brown   This method currently only works with autonomous ODE and DAE.
156061692a83SJed Brown 
1561d0685a90SJed Brown   Consider trying TSARKIMEX if the stiff part is strongly nonlinear.
1562d0685a90SJed Brown 
15633d5a8a6aSBarry 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
15643d5a8a6aSBarry Smith 
1565e94cfbe0SPatrick Sanan   Developer Notes:
156661692a83SJed Brown   Rosenbrock-W methods are typically specified for autonomous ODE
156761692a83SJed Brown 
1568f9c1d6abSBarry Smith $  udot = f(u)
156961692a83SJed Brown 
157061692a83SJed Brown   by the stage equations
157161692a83SJed Brown 
1572f9c1d6abSBarry Smith $  k_i = h f(u_0 + sum_j alpha_ij k_j) + h J sum_j gamma_ij k_j
157361692a83SJed Brown 
157461692a83SJed Brown   and step completion formula
157561692a83SJed Brown 
1576f9c1d6abSBarry Smith $  u_1 = u_0 + sum_j b_j k_j
157761692a83SJed Brown 
1578f9c1d6abSBarry Smith   with step size h and coefficients alpha_ij, gamma_ij, and b_i. Implementing the method in this form would require f(u)
157961692a83SJed Brown   and the Jacobian J to be available, in addition to the shifted matrix I - h gamma_ii J. Following Hairer and Wanner,
158061692a83SJed Brown   we define new variables for the stage equations
158161692a83SJed Brown 
158261692a83SJed Brown $  y_i = gamma_ij k_j
158361692a83SJed Brown 
158461692a83SJed Brown   The k_j can be recovered because Gamma is invertible. Let C be the lower triangular part of Gamma^{-1} and define
158561692a83SJed Brown 
1586b70472e2SJed Brown $  A = Alpha Gamma^{-1}, bt^T = b^T Gamma^{-1}
158761692a83SJed Brown 
158861692a83SJed Brown   to rewrite the method as
158961692a83SJed Brown 
1590f9c1d6abSBarry 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
1591f9c1d6abSBarry Smith $  u_1 = u_0 + sum_j bt_j y_j
159261692a83SJed Brown 
159361692a83SJed Brown    where we have introduced the mass matrix M. Continue by defining
159461692a83SJed Brown 
159561692a83SJed Brown $  ydot_i = 1/(h gamma_ii) y_i - sum_j (c_ij/h) y_j
159661692a83SJed Brown 
159761692a83SJed Brown    or, more compactly in tensor notation
159861692a83SJed Brown 
159961692a83SJed Brown $  Ydot = 1/h (Gamma^{-1} \otimes I) Y .
160061692a83SJed Brown 
160161692a83SJed Brown    Note that Gamma^{-1} is lower triangular. With this definition of Ydot in terms of known quantities and the current
160261692a83SJed Brown    stage y_i, the stage equations reduce to performing one Newton step (typically with a lagged Jacobian) on the
160361692a83SJed Brown    equation
160461692a83SJed Brown 
1605f9c1d6abSBarry Smith $  g(u_0 + sum_j a_ij y_j + y_i, ydot_i) = 0
160661692a83SJed Brown 
160761692a83SJed Brown    with initial guess y_i = 0.
1608e27a552bSJed Brown 
1609e27a552bSJed Brown   Level: beginner
1610e27a552bSJed Brown 
1611d0685a90SJed Brown .seealso:  TSCreate(), TS, TSSetType(), TSRosWSetType(), TSRosWRegister(), TSROSWTHETA1, TSROSWTHETA2, TSROSW2M, TSROSW2P, TSROSWRA3PW, TSROSWRA34PW2, TSROSWRODAS3,
1612a4386c9eSJed Brown            TSROSWSANDU3, TSROSWASSP3P3S1C, TSROSWLASSP3P4S2C, TSROSWLLSSP3P4S2C, TSROSWGRK4T, TSROSWSHAMP4, TSROSWVELDD4, TSROSW4L
1613e27a552bSJed Brown M*/
16148cc058d9SJed Brown PETSC_EXTERN PetscErrorCode TSCreate_RosW(TS ts)
1615e27a552bSJed Brown {
161661692a83SJed Brown   TS_RosW        *ros;
1617e27a552bSJed Brown 
1618e27a552bSJed Brown   PetscFunctionBegin;
16199566063dSJacob Faibussowitsch   PetscCall(TSRosWInitializePackage());
1620e27a552bSJed Brown 
1621e27a552bSJed Brown   ts->ops->reset          = TSReset_RosW;
1622e27a552bSJed Brown   ts->ops->destroy        = TSDestroy_RosW;
1623e27a552bSJed Brown   ts->ops->view           = TSView_RosW;
16249200755eSBarry Smith   ts->ops->load           = TSLoad_RosW;
1625e27a552bSJed Brown   ts->ops->setup          = TSSetUp_RosW;
1626e27a552bSJed Brown   ts->ops->step           = TSStep_RosW;
1627e27a552bSJed Brown   ts->ops->interpolate    = TSInterpolate_RosW;
16281c3436cfSJed Brown   ts->ops->evaluatestep   = TSEvaluateStep_RosW;
162924655328SShri   ts->ops->rollback       = TSRollBack_RosW;
1630e27a552bSJed Brown   ts->ops->setfromoptions = TSSetFromOptions_RosW;
1631e27a552bSJed Brown   ts->ops->snesfunction   = SNESTSFormFunction_RosW;
1632e27a552bSJed Brown   ts->ops->snesjacobian   = SNESTSFormJacobian_RosW;
1633e27a552bSJed Brown 
1634efd4aadfSBarry Smith   ts->usessnes = PETSC_TRUE;
1635efd4aadfSBarry Smith 
16369566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(ts,&ros));
163761692a83SJed Brown   ts->data = (void*)ros;
1638e27a552bSJed Brown 
16399566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)ts,"TSRosWGetType_C",TSRosWGetType_RosW));
16409566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)ts,"TSRosWSetType_C",TSRosWSetType_RosW));
16419566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)ts,"TSRosWSetRecomputeJacobian_C",TSRosWSetRecomputeJacobian_RosW));
1642b39943a6SLisandro Dalcin 
16439566063dSJacob Faibussowitsch   PetscCall(TSRosWSetType(ts,TSRosWDefault));
1644e27a552bSJed Brown   PetscFunctionReturn(0);
1645e27a552bSJed Brown }
1646