xref: /petsc/src/ts/impls/rosw/rosw.c (revision ce94432eddcd14845bc7e8083b7f8ea723b9bf7d)
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 */
13b45d2f2cSJed Brown #include <petsc-private/tsimpl.h>                /*I   "petscts.h"   I*/
14e27a552bSJed Brown 
1561692a83SJed Brown #include <../src/mat/blockinvert.h>
1661692a83SJed Brown 
1719fd82e9SBarry Smith static TSRosWType TSRosWDefault = TSROSWRA34PW2;
18e27a552bSJed Brown static PetscBool  TSRosWRegisterAllCalled;
19e27a552bSJed Brown static PetscBool  TSRosWPackageInitialized;
20e27a552bSJed Brown 
2161692a83SJed Brown typedef struct _RosWTableau *RosWTableau;
2261692a83SJed Brown struct _RosWTableau {
23e27a552bSJed Brown   char      *name;
24e27a552bSJed Brown   PetscInt  order;              /* Classical approximation order of the method */
25e27a552bSJed Brown   PetscInt  s;                  /* Number of stages */
26f4aed992SEmil Constantinescu   PetscInt  pinterp;            /* Interpolation order */
2761692a83SJed Brown   PetscReal *A;                 /* Propagation table, strictly lower triangular */
2861692a83SJed Brown   PetscReal *Gamma;             /* Stage table, lower triangular with nonzero diagonal */
29c17803e7SJed Brown   PetscBool *GammaZeroDiag;     /* Diagonal entries that are zero in stage table Gamma, vector indicating explicit statages */
3043b21953SEmil Constantinescu   PetscReal *GammaExplicitCorr; /* Coefficients for correction terms needed for explicit stages in transformed variables*/
3161692a83SJed Brown   PetscReal *b;                 /* Step completion table */
32fe7e6d57SJed Brown   PetscReal *bembed;            /* Step completion table for embedded method of order one less */
3361692a83SJed Brown   PetscReal *ASum;              /* Row sum of A */
3461692a83SJed Brown   PetscReal *GammaSum;          /* Row sum of Gamma, only needed for non-autonomous systems */
3561692a83SJed Brown   PetscReal *At;                /* Propagation table in transformed variables */
3661692a83SJed Brown   PetscReal *bt;                /* Step completion table in transformed variables */
37fe7e6d57SJed Brown   PetscReal *bembedt;           /* Step completion table of order one less in transformed variables */
3861692a83SJed Brown   PetscReal *GammaInv;          /* Inverse of Gamma, used for transformed variables */
398d59e960SJed Brown   PetscReal ccfl;               /* Placeholder for CFL coefficient relative to forward Euler */
403ca35412SEmil Constantinescu   PetscReal *binterpt;          /* Dense output formula */
41e27a552bSJed Brown };
4261692a83SJed Brown typedef struct _RosWTableauLink *RosWTableauLink;
4361692a83SJed Brown struct _RosWTableauLink {
4461692a83SJed Brown   struct _RosWTableau tab;
4561692a83SJed Brown   RosWTableauLink     next;
46e27a552bSJed Brown };
4761692a83SJed Brown static RosWTableauLink RosWTableauList;
48e27a552bSJed Brown 
49e27a552bSJed Brown typedef struct {
5061692a83SJed Brown   RosWTableau  tableau;
5161692a83SJed Brown   Vec          *Y;               /* States computed during the step, used to complete the step */
52e27a552bSJed Brown   Vec          Ydot;             /* Work vector holding Ydot during residual evaluation */
5361692a83SJed Brown   Vec          Ystage;           /* Work vector for the state value at each stage */
5461692a83SJed Brown   Vec          Zdot;             /* Ydot = Zdot + shift*Y */
5561692a83SJed Brown   Vec          Zstage;           /* Y = Zstage + Y */
563ca35412SEmil Constantinescu   Vec          VecSolPrev;       /* Work vector holding the solution from the previous step (used for interpolation)*/
571c3436cfSJed Brown   PetscScalar  *work;            /* Scalar work space of length number of stages, used to prepare VecMAXPY() */
58b296d7d5SJed Brown   PetscReal    scoeff;           /* shift = scoeff/dt */
59e27a552bSJed Brown   PetscReal    stage_time;
60c17803e7SJed Brown   PetscReal    stage_explicit;     /* Flag indicates that the current stage is explicit */
6161692a83SJed Brown   PetscBool    recompute_jacobian; /* Recompute the Jacobian at each stage, default is to freeze the Jacobian at the start of each step */
62108c343cSJed Brown   TSStepStatus status;
63e27a552bSJed Brown } TS_RosW;
64e27a552bSJed Brown 
65fe7e6d57SJed Brown /*MC
663606a31eSEmil Constantinescu      TSROSWTHETA1 - One stage first order L-stable Rosenbrock-W scheme (aka theta method).
673606a31eSEmil Constantinescu 
683606a31eSEmil Constantinescu      Only an approximate Jacobian is needed.
693606a31eSEmil Constantinescu 
703606a31eSEmil Constantinescu      Level: intermediate
713606a31eSEmil Constantinescu 
723606a31eSEmil Constantinescu .seealso: TSROSW
733606a31eSEmil Constantinescu M*/
743606a31eSEmil Constantinescu 
753606a31eSEmil Constantinescu /*MC
763606a31eSEmil Constantinescu      TSROSWTHETA2 - One stage second order A-stable Rosenbrock-W scheme (aka theta method).
773606a31eSEmil Constantinescu 
783606a31eSEmil Constantinescu      Only an approximate Jacobian is needed.
793606a31eSEmil Constantinescu 
803606a31eSEmil Constantinescu      Level: intermediate
813606a31eSEmil Constantinescu 
823606a31eSEmil Constantinescu .seealso: TSROSW
833606a31eSEmil Constantinescu M*/
843606a31eSEmil Constantinescu 
853606a31eSEmil Constantinescu /*MC
86fe7e6d57SJed Brown      TSROSW2M - Two stage second order L-stable Rosenbrock-W scheme.
87fe7e6d57SJed Brown 
88fe7e6d57SJed Brown      Only an approximate Jacobian is needed. By default, it is only recomputed once per step. This method is a reflection of TSROSW2P.
89fe7e6d57SJed Brown 
90fe7e6d57SJed Brown      Level: intermediate
91fe7e6d57SJed Brown 
92fe7e6d57SJed Brown .seealso: TSROSW
93fe7e6d57SJed Brown M*/
94fe7e6d57SJed Brown 
95fe7e6d57SJed Brown /*MC
96fe7e6d57SJed Brown      TSROSW2P - Two stage second order L-stable Rosenbrock-W scheme.
97fe7e6d57SJed Brown 
98fe7e6d57SJed Brown      Only an approximate Jacobian is needed. By default, it is only recomputed once per step. This method is a reflection of TSROSW2M.
99fe7e6d57SJed Brown 
100fe7e6d57SJed Brown      Level: intermediate
101fe7e6d57SJed Brown 
102fe7e6d57SJed Brown .seealso: TSROSW
103fe7e6d57SJed Brown M*/
104fe7e6d57SJed Brown 
105fe7e6d57SJed Brown /*MC
106fe7e6d57SJed Brown      TSROSWRA3PW - Three stage third order Rosenbrock-W scheme for PDAE of index 1.
107fe7e6d57SJed Brown 
108fe7e6d57SJed Brown      Only an approximate Jacobian is needed. By default, it is only recomputed once per step.
109fe7e6d57SJed Brown 
110fe7e6d57SJed 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.
111fe7e6d57SJed Brown 
112fe7e6d57SJed Brown      References:
113fe7e6d57SJed Brown      Rang and Angermann, New Rosenbrock-W methods of order 3 for partial differential algebraic equations of index 1, 2005.
114fe7e6d57SJed Brown 
115fe7e6d57SJed Brown      Level: intermediate
116fe7e6d57SJed Brown 
117fe7e6d57SJed Brown .seealso: TSROSW
118fe7e6d57SJed Brown M*/
119fe7e6d57SJed Brown 
120fe7e6d57SJed Brown /*MC
121fe7e6d57SJed Brown      TSROSWRA34PW2 - Four stage third order L-stable Rosenbrock-W scheme for PDAE of index 1.
122fe7e6d57SJed Brown 
123fe7e6d57SJed Brown      Only an approximate Jacobian is needed. By default, it is only recomputed once per step.
124fe7e6d57SJed Brown 
125fe7e6d57SJed 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.
126fe7e6d57SJed Brown 
127fe7e6d57SJed Brown      References:
128fe7e6d57SJed Brown      Rang and Angermann, New Rosenbrock-W methods of order 3 for partial differential algebraic equations of index 1, 2005.
129fe7e6d57SJed Brown 
130fe7e6d57SJed Brown      Level: intermediate
131fe7e6d57SJed Brown 
132fe7e6d57SJed Brown .seealso: TSROSW
133fe7e6d57SJed Brown M*/
134fe7e6d57SJed Brown 
135ef3c5b88SJed Brown /*MC
136ef3c5b88SJed Brown      TSROSWRODAS3 - Four stage third order L-stable Rosenbrock scheme
137ef3c5b88SJed Brown 
138ef3c5b88SJed Brown      By default, the Jacobian is only recomputed once per step.
139ef3c5b88SJed Brown 
140ef3c5b88SJed Brown      Both the third order and embedded second order methods are stiffly accurate and L-stable.
141ef3c5b88SJed Brown 
142ef3c5b88SJed Brown      References:
143ef3c5b88SJed Brown      Sandu et al, Benchmarking stiff ODE solvers for atmospheric chemistry problems II, Rosenbrock solvers, 1997.
144ef3c5b88SJed Brown 
145ef3c5b88SJed Brown      Level: intermediate
146ef3c5b88SJed Brown 
147ef3c5b88SJed Brown .seealso: TSROSW, TSROSWSANDU3
148ef3c5b88SJed Brown M*/
149ef3c5b88SJed Brown 
150ef3c5b88SJed Brown /*MC
151ef3c5b88SJed Brown      TSROSWSANDU3 - Three stage third order L-stable Rosenbrock scheme
152ef3c5b88SJed Brown 
153ef3c5b88SJed Brown      By default, the Jacobian is only recomputed once per step.
154ef3c5b88SJed Brown 
155ef3c5b88SJed Brown      The third order method is L-stable, but not stiffly accurate.
156ef3c5b88SJed Brown      The second order embedded method is strongly A-stable with R(infty) = 0.5.
157ef3c5b88SJed Brown      The internal stages are L-stable.
158ef3c5b88SJed Brown      This method is called ROS3 in the paper.
159ef3c5b88SJed Brown 
160ef3c5b88SJed Brown      References:
161ef3c5b88SJed Brown      Sandu et al, Benchmarking stiff ODE solvers for atmospheric chemistry problems II, Rosenbrock solvers, 1997.
162ef3c5b88SJed Brown 
163ef3c5b88SJed Brown      Level: intermediate
164ef3c5b88SJed Brown 
165ef3c5b88SJed Brown .seealso: TSROSW, TSROSWRODAS3
166ef3c5b88SJed Brown M*/
167ef3c5b88SJed Brown 
168961f28d0SJed Brown /*MC
169961f28d0SJed Brown      TSROSWASSP3P3S1C - A-stable Rosenbrock-W method with SSP explicit part, third order, three stages
170961f28d0SJed Brown 
171961f28d0SJed Brown      By default, the Jacobian is only recomputed once per step.
172961f28d0SJed Brown 
173961f28d0SJed Brown      A-stable SPP explicit order 3, 3 stages, CFL 1 (eff = 1/3)
174961f28d0SJed Brown 
175961f28d0SJed Brown      References:
176961f28d0SJed Brown      Emil Constantinescu
177961f28d0SJed Brown 
178961f28d0SJed Brown      Level: intermediate
179961f28d0SJed Brown 
18043b21953SEmil Constantinescu .seealso: TSROSW, TSROSWLASSP3P4S2C, TSROSWLLSSP3P4S2C, SSP
181961f28d0SJed Brown M*/
182961f28d0SJed Brown 
183961f28d0SJed Brown /*MC
184998eb97aSJed Brown      TSROSWLASSP3P4S2C - L-stable Rosenbrock-W method with SSP explicit part, third order, four stages
185961f28d0SJed Brown 
186961f28d0SJed Brown      By default, the Jacobian is only recomputed once per step.
187961f28d0SJed Brown 
188961f28d0SJed Brown      L-stable (A-stable embedded) SPP explicit order 3, 4 stages, CFL 2 (eff = 1/2)
189961f28d0SJed Brown 
190961f28d0SJed Brown      References:
191961f28d0SJed Brown      Emil Constantinescu
192961f28d0SJed Brown 
193961f28d0SJed Brown      Level: intermediate
194961f28d0SJed Brown 
19543b21953SEmil Constantinescu .seealso: TSROSW, TSROSWASSP3P3S1C, TSROSWLLSSP3P4S2C, TSSSP
196961f28d0SJed Brown M*/
197961f28d0SJed Brown 
198961f28d0SJed Brown /*MC
199998eb97aSJed Brown      TSROSWLLSSP3P4S2C - L-stable Rosenbrock-W method with SSP explicit part, third order, four stages
200961f28d0SJed Brown 
201961f28d0SJed Brown      By default, the Jacobian is only recomputed once per step.
202961f28d0SJed Brown 
203961f28d0SJed Brown      L-stable (L-stable embedded) SPP explicit order 3, 4 stages, CFL 2 (eff = 1/2)
204961f28d0SJed Brown 
205961f28d0SJed Brown      References:
206961f28d0SJed Brown      Emil Constantinescu
207961f28d0SJed Brown 
208961f28d0SJed Brown      Level: intermediate
209961f28d0SJed Brown 
210961f28d0SJed Brown .seealso: TSROSW, TSROSWASSP3P3S1C, TSROSWLASSP3P4S2C, TSSSP
211961f28d0SJed Brown M*/
212961f28d0SJed Brown 
21342faf41dSJed Brown /*MC
21442faf41dSJed Brown      TSROSWGRK4T - four stage, fourth order Rosenbrock (not W) method from Kaps and Rentrop
21542faf41dSJed Brown 
21642faf41dSJed Brown      By default, the Jacobian is only recomputed once per step.
21742faf41dSJed Brown 
21842faf41dSJed Brown      A(89.3 degrees)-stable, |R(infty)| = 0.454.
21942faf41dSJed Brown 
22042faf41dSJed Brown      This method does not provide a dense output formula.
22142faf41dSJed Brown 
22242faf41dSJed Brown      References:
22342faf41dSJed Brown      Kaps and Rentrop, Generalized Runge-Kutta methods of order four with stepsize control for stiff ordinary differential equations, 1979.
22442faf41dSJed Brown 
22542faf41dSJed Brown      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:
24442faf41dSJed Brown      Shampine, Implementation of Rosenbrock methods, 1982.
24542faf41dSJed Brown 
24642faf41dSJed Brown      Hairer and Wanner, Solving Ordinary Differential Equations II, Section 4 Table 7.2.
24742faf41dSJed Brown 
24842faf41dSJed Brown      Hairer's code ros4.f
24942faf41dSJed Brown 
25042faf41dSJed Brown      Level: intermediate
25142faf41dSJed Brown 
25242faf41dSJed Brown .seealso: TSROSW, TSROSWGRK4T, TSROSWVELDD4, TSROSW4L
25342faf41dSJed Brown M*/
25442faf41dSJed Brown 
25542faf41dSJed Brown /*MC
25642faf41dSJed Brown      TSROSWVELDD4 - four stage, fourth order Rosenbrock (not W) method from van Veldhuizen
25742faf41dSJed Brown 
25842faf41dSJed Brown      By default, the Jacobian is only recomputed once per step.
25942faf41dSJed Brown 
26042faf41dSJed Brown      A(89.5 degrees)-stable, |R(infty)| = 0.24.
26142faf41dSJed Brown 
26242faf41dSJed Brown      This method does not provide a dense output formula.
26342faf41dSJed Brown 
26442faf41dSJed Brown      References:
26542faf41dSJed Brown      van Veldhuizen, D-stability and Kaps-Rentrop methods, 1984.
26642faf41dSJed Brown 
26742faf41dSJed Brown      Hairer and Wanner, Solving Ordinary Differential Equations II, Section 4 Table 7.2.
26842faf41dSJed Brown 
26942faf41dSJed Brown      Hairer's code ros4.f
27042faf41dSJed Brown 
27142faf41dSJed Brown      Level: intermediate
27242faf41dSJed Brown 
27342faf41dSJed Brown .seealso: TSROSW, TSROSWGRK4T, TSROSWSHAMP4, TSROSW4L
27442faf41dSJed Brown M*/
27542faf41dSJed Brown 
27642faf41dSJed Brown /*MC
27742faf41dSJed Brown      TSROSW4L - four stage, fourth order Rosenbrock (not W) method
27842faf41dSJed Brown 
27942faf41dSJed Brown      By default, the Jacobian is only recomputed once per step.
28042faf41dSJed Brown 
28142faf41dSJed Brown      A-stable and L-stable
28242faf41dSJed Brown 
28342faf41dSJed Brown      This method does not provide a dense output formula.
28442faf41dSJed Brown 
28542faf41dSJed Brown      References:
28642faf41dSJed Brown      Hairer and Wanner, Solving Ordinary Differential Equations II, Section 4 Table 7.2.
28742faf41dSJed Brown 
28842faf41dSJed Brown      Hairer's code ros4.f
28942faf41dSJed Brown 
29042faf41dSJed Brown      Level: intermediate
29142faf41dSJed Brown 
29242faf41dSJed Brown .seealso: TSROSW, TSROSWGRK4T, TSROSWSHAMP4, TSROSW4L
29342faf41dSJed Brown M*/
29442faf41dSJed Brown 
295e27a552bSJed Brown #undef __FUNCT__
296e27a552bSJed Brown #define __FUNCT__ "TSRosWRegisterAll"
297e27a552bSJed Brown /*@C
298e27a552bSJed Brown   TSRosWRegisterAll - Registers all of the additive Runge-Kutta implicit-explicit methods in TSRosW
299e27a552bSJed Brown 
300e27a552bSJed Brown   Not Collective, but should be called by all processes which will need the schemes to be registered
301e27a552bSJed Brown 
302e27a552bSJed Brown   Level: advanced
303e27a552bSJed Brown 
304e27a552bSJed Brown .keywords: TS, TSRosW, register, all
305e27a552bSJed Brown 
306e27a552bSJed Brown .seealso:  TSRosWRegisterDestroy()
307e27a552bSJed Brown @*/
308e27a552bSJed Brown PetscErrorCode TSRosWRegisterAll(void)
309e27a552bSJed Brown {
310e27a552bSJed Brown   PetscErrorCode ierr;
311e27a552bSJed Brown 
312e27a552bSJed Brown   PetscFunctionBegin;
313e27a552bSJed Brown   if (TSRosWRegisterAllCalled) PetscFunctionReturn(0);
314e27a552bSJed Brown   TSRosWRegisterAllCalled = PETSC_TRUE;
315e27a552bSJed Brown 
316e27a552bSJed Brown   {
317bbd56ea5SKarl Rupp     const PetscReal A = 0;
318bbd56ea5SKarl Rupp     const PetscReal Gamma = 1;
319bbd56ea5SKarl Rupp     const PetscReal b = 1;
320bbd56ea5SKarl Rupp     const PetscReal binterpt=1;
3211f80e275SEmil Constantinescu 
3220298fd71SBarry Smith     ierr = TSRosWRegister(TSROSWTHETA1,1,1,&A,&Gamma,&b,NULL,1,&binterpt);CHKERRQ(ierr);
3233606a31eSEmil Constantinescu   }
3243606a31eSEmil Constantinescu 
3253606a31eSEmil Constantinescu   {
326bbd56ea5SKarl Rupp     const PetscReal A = 0;
327bbd56ea5SKarl Rupp     const PetscReal Gamma = 0.5;
328bbd56ea5SKarl Rupp     const PetscReal b = 1;
329bbd56ea5SKarl Rupp     const PetscReal binterpt=1;
330bbd56ea5SKarl Rupp 
3310298fd71SBarry Smith     ierr = TSRosWRegister(TSROSWTHETA2,2,1,&A,&Gamma,&b,NULL,1,&binterpt);CHKERRQ(ierr);
3323606a31eSEmil Constantinescu   }
3333606a31eSEmil Constantinescu 
3343606a31eSEmil Constantinescu   {
335da80777bSKarl 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. */
336e27a552bSJed Brown     const PetscReal
33761692a83SJed Brown       A[2][2]     = {{0,0}, {1.,0}},
338da80777bSKarl Rupp       Gamma[2][2] = {{1.707106781186547524401,0}, {-2.*1.707106781186547524401,1.707106781186547524401}},
3391c3436cfSJed Brown       b[2]        = {0.5,0.5},
3401c3436cfSJed Brown       b1[2]       = {1.0,0.0};
3411f80e275SEmil Constantinescu     PetscReal binterpt[2][2];
342da80777bSKarl Rupp     binterpt[0][0] = 1.707106781186547524401 - 1.0;
343da80777bSKarl Rupp     binterpt[1][0] = 2.0 - 1.707106781186547524401;
344da80777bSKarl Rupp     binterpt[0][1] = 1.707106781186547524401 - 1.5;
345da80777bSKarl Rupp     binterpt[1][1] = 1.5 - 1.707106781186547524401;
346bbd56ea5SKarl Rupp 
3471f80e275SEmil Constantinescu     ierr = TSRosWRegister(TSROSW2P,2,2,&A[0][0],&Gamma[0][0],b,b1,2,&binterpt[0][0]);CHKERRQ(ierr);
348e27a552bSJed Brown   }
349e27a552bSJed Brown   {
350da80777bSKarl 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. */
351e27a552bSJed Brown     const PetscReal
35261692a83SJed Brown       A[2][2]     = {{0,0}, {1.,0}},
353da80777bSKarl Rupp       Gamma[2][2] = {{0.2928932188134524755992,0}, {-2.*0.2928932188134524755992,0.2928932188134524755992}},
3541c3436cfSJed Brown       b[2]        = {0.5,0.5},
3551c3436cfSJed Brown       b1[2]       = {1.0,0.0};
3561f80e275SEmil Constantinescu     PetscReal binterpt[2][2];
357da80777bSKarl Rupp     binterpt[0][0] = 0.2928932188134524755992 - 1.0;
358da80777bSKarl Rupp     binterpt[1][0] = 2.0 - 0.2928932188134524755992;
359da80777bSKarl Rupp     binterpt[0][1] = 0.2928932188134524755992 - 1.5;
360da80777bSKarl Rupp     binterpt[1][1] = 1.5 - 0.2928932188134524755992;
361bbd56ea5SKarl Rupp 
3621f80e275SEmil Constantinescu     ierr = TSRosWRegister(TSROSW2M,2,2,&A[0][0],&Gamma[0][0],b,b1,2,&binterpt[0][0]);CHKERRQ(ierr);
363fe7e6d57SJed Brown   }
364fe7e6d57SJed Brown   {
365da80777bSKarl Rupp     /*const PetscReal g = 7.8867513459481287e-01; Directly written in-place below */
3661f80e275SEmil Constantinescu     PetscReal binterpt[3][2];
367fe7e6d57SJed Brown     const PetscReal
368fe7e6d57SJed Brown       A[3][3] = {{0,0,0},
369fe7e6d57SJed Brown                  {1.5773502691896257e+00,0,0},
370fe7e6d57SJed Brown                  {0.5,0,0}},
371da80777bSKarl Rupp       Gamma[3][3] = {{7.8867513459481287e-01,0,0},
372da80777bSKarl Rupp                      {-1.5773502691896257e+00,7.8867513459481287e-01,0},
373da80777bSKarl Rupp                      {-6.7075317547305480e-01,-1.7075317547305482e-01,7.8867513459481287e-01}},
374fe7e6d57SJed Brown       b[3]  = {1.0566243270259355e-01,4.9038105676657971e-02,8.4529946162074843e-01},
375fe7e6d57SJed Brown       b2[3] = {-1.7863279495408180e-01,1./3.,8.4529946162074843e-01};
3761f80e275SEmil Constantinescu 
3771f80e275SEmil Constantinescu       binterpt[0][0] = -0.8094010767585034;
3781f80e275SEmil Constantinescu       binterpt[1][0] = -0.5;
3791f80e275SEmil Constantinescu       binterpt[2][0] = 2.3094010767585034;
3801f80e275SEmil Constantinescu       binterpt[0][1] = 0.9641016151377548;
3811f80e275SEmil Constantinescu       binterpt[1][1] = 0.5;
3821f80e275SEmil Constantinescu       binterpt[2][1] = -1.4641016151377548;
383bbd56ea5SKarl Rupp 
3841f80e275SEmil Constantinescu       ierr = TSRosWRegister(TSROSWRA3PW,3,3,&A[0][0],&Gamma[0][0],b,b2,2,&binterpt[0][0]);CHKERRQ(ierr);
385fe7e6d57SJed Brown   }
386fe7e6d57SJed Brown   {
3873ca35412SEmil Constantinescu     PetscReal  binterpt[4][3];
388da80777bSKarl Rupp     /*const PetscReal g = 4.3586652150845900e-01; Directly written in-place below */
389fe7e6d57SJed Brown     const PetscReal
390fe7e6d57SJed Brown       A[4][4] = {{0,0,0,0},
391fe7e6d57SJed Brown                  {8.7173304301691801e-01,0,0,0},
392fe7e6d57SJed Brown                  {8.4457060015369423e-01,-1.1299064236484185e-01,0,0},
393fe7e6d57SJed Brown                  {0,0,1.,0}},
394da80777bSKarl Rupp       Gamma[4][4] = {{4.3586652150845900e-01,0,0,0},
395da80777bSKarl Rupp                      {-8.7173304301691801e-01,4.3586652150845900e-01,0,0},
396da80777bSKarl Rupp                      {-9.0338057013044082e-01,5.4180672388095326e-02,4.3586652150845900e-01,0},
397da80777bSKarl Rupp                      {2.4212380706095346e-01,-1.2232505839045147e+00,5.4526025533510214e-01,4.3586652150845900e-01}},
398fe7e6d57SJed Brown       b[4]  = {2.4212380706095346e-01,-1.2232505839045147e+00,1.5452602553351020e+00,4.3586652150845900e-01},
3993ca35412SEmil Constantinescu       b2[4] = {3.7810903145819369e-01,-9.6042292212423178e-02,5.0000000000000000e-01,2.1793326075422950e-01};
4003ca35412SEmil Constantinescu 
4013ca35412SEmil Constantinescu     binterpt[0][0]=1.0564298455794094;
4023ca35412SEmil Constantinescu     binterpt[1][0]=2.296429974281067;
4033ca35412SEmil Constantinescu     binterpt[2][0]=-1.307599564525376;
4043ca35412SEmil Constantinescu     binterpt[3][0]=-1.045260255335102;
4053ca35412SEmil Constantinescu     binterpt[0][1]=-1.3864882699759573;
4063ca35412SEmil Constantinescu     binterpt[1][1]=-8.262611700275677;
4073ca35412SEmil Constantinescu     binterpt[2][1]=7.250979895056055;
4083ca35412SEmil Constantinescu     binterpt[3][1]=2.398120075195581;
4093ca35412SEmil Constantinescu     binterpt[0][2]=0.5721822314575016;
4103ca35412SEmil Constantinescu     binterpt[1][2]=4.742931142090097;
4113ca35412SEmil Constantinescu     binterpt[2][2]=-4.398120075195578;
4123ca35412SEmil Constantinescu     binterpt[3][2]=-0.9169932983520199;
4133ca35412SEmil Constantinescu 
4143ca35412SEmil Constantinescu     ierr = TSRosWRegister(TSROSWRA34PW2,3,4,&A[0][0],&Gamma[0][0],b,b2,3,&binterpt[0][0]);CHKERRQ(ierr);
415e27a552bSJed Brown   }
416ef3c5b88SJed Brown   {
417da80777bSKarl Rupp     /* const PetscReal g = 0.5;       Directly written in-place below */
418ef3c5b88SJed Brown     const PetscReal
419ef3c5b88SJed Brown       A[4][4] = {{0,0,0,0},
420ef3c5b88SJed Brown                  {0,0,0,0},
421ef3c5b88SJed Brown                  {1.,0,0,0},
422ef3c5b88SJed Brown                  {0.75,-0.25,0.5,0}},
423da80777bSKarl Rupp       Gamma[4][4] = {{0.5,0,0,0},
424da80777bSKarl Rupp                      {1.,0.5,0,0},
425da80777bSKarl Rupp                      {-0.25,-0.25,0.5,0},
426da80777bSKarl Rupp                      {1./12,1./12,-2./3,0.5}},
427ef3c5b88SJed Brown       b[4]  = {5./6,-1./6,-1./6,0.5},
428ef3c5b88SJed Brown       b2[4] = {0.75,-0.25,0.5,0};
429bbd56ea5SKarl Rupp 
4300298fd71SBarry Smith     ierr = TSRosWRegister(TSROSWRODAS3,3,4,&A[0][0],&Gamma[0][0],b,b2,0,NULL);CHKERRQ(ierr);
431ef3c5b88SJed Brown   }
432ef3c5b88SJed Brown   {
433da80777bSKarl Rupp     /*const PetscReal g = 0.43586652150845899941601945119356;       Directly written in-place below */
434ef3c5b88SJed Brown     const PetscReal
435ef3c5b88SJed Brown       A[3][3] = {{0,0,0},
436da80777bSKarl Rupp                  {0.43586652150845899941601945119356,0,0},
437da80777bSKarl Rupp                  {0.43586652150845899941601945119356,0,0}},
438da80777bSKarl Rupp       Gamma[3][3] = {{0.43586652150845899941601945119356,0,0},
439da80777bSKarl Rupp                      {-0.19294655696029095575009695436041,0.43586652150845899941601945119356,0},
440da80777bSKarl Rupp                      {0,1.74927148125794685173529749738960,0.43586652150845899941601945119356}},
441ef3c5b88SJed Brown       b[3]  = {-0.75457412385404315829818998646589,1.94100407061964420292840123379419,-0.18642994676560104463021124732829},
442ef3c5b88SJed Brown       b2[3] = {-1.53358745784149585370766523913002,2.81745131148625772213931745457622,-0.28386385364476186843165221544619};
4431f80e275SEmil Constantinescu 
4441f80e275SEmil Constantinescu     PetscReal binterpt[3][2];
4451f80e275SEmil Constantinescu     binterpt[0][0] = 3.793692883777660870425141387941;
4461f80e275SEmil Constantinescu     binterpt[1][0] = -2.918692883777660870425141387941;
4471f80e275SEmil Constantinescu     binterpt[2][0] = 0.125;
4481f80e275SEmil Constantinescu     binterpt[0][1] = -0.725741064379812106687651020584;
4491f80e275SEmil Constantinescu     binterpt[1][1] = 0.559074397713145440020984353917;
4501f80e275SEmil Constantinescu     binterpt[2][1] = 0.16666666666666666666666666666667;
4511f80e275SEmil Constantinescu 
4521f80e275SEmil Constantinescu     ierr = TSRosWRegister(TSROSWSANDU3,3,3,&A[0][0],&Gamma[0][0],b,b2,2,&binterpt[0][0]);CHKERRQ(ierr);
453ef3c5b88SJed Brown   }
454b1c69cc3SEmil Constantinescu   {
455da80777bSKarl Rupp     /*const PetscReal s3 = PetscSqrtReal(3.),g = (3.0+s3)/6.0;
456da80777bSKarl Rupp      * Direct evaluation: s3 = 1.732050807568877293527;
457da80777bSKarl Rupp      *                     g = 0.7886751345948128822546;
458da80777bSKarl Rupp      * Values are directly inserted below to ensure availability at compile time (compiler warnings otherwise...) */
459b1c69cc3SEmil Constantinescu     const PetscReal
460b1c69cc3SEmil Constantinescu       A[3][3] = {{0,0,0},
461b1c69cc3SEmil Constantinescu                  {1,0,0},
462b1c69cc3SEmil Constantinescu                  {0.25,0.25,0}},
463b1c69cc3SEmil Constantinescu       Gamma[3][3] = {{0,0,0},
464da80777bSKarl Rupp                      {(-3.0-1.732050807568877293527)/6.0,0.7886751345948128822546,0},
465da80777bSKarl Rupp                      {(-3.0-1.732050807568877293527)/24.0,(-3.0-1.732050807568877293527)/8.0,0.7886751345948128822546}},
466b1c69cc3SEmil Constantinescu       b[3]  = {1./6.,1./6.,2./3.},
467b1c69cc3SEmil Constantinescu       b2[3] = {1./4.,1./4.,1./2.};
468c0cb691aSEmil Constantinescu     PetscReal binterpt[3][2];
469da80777bSKarl Rupp 
470c0cb691aSEmil Constantinescu     binterpt[0][0]=0.089316397477040902157517886164709;
471c0cb691aSEmil Constantinescu     binterpt[1][0]=-0.91068360252295909784248211383529;
472c0cb691aSEmil Constantinescu     binterpt[2][0]=1.8213672050459181956849642276706;
473c0cb691aSEmil Constantinescu     binterpt[0][1]=0.077350269189625764509148780501957;
474c0cb691aSEmil Constantinescu     binterpt[1][1]=1.077350269189625764509148780502;
475c0cb691aSEmil Constantinescu     binterpt[2][1]=-1.1547005383792515290182975610039;
476bbd56ea5SKarl Rupp 
477c0cb691aSEmil Constantinescu     ierr = TSRosWRegister(TSROSWASSP3P3S1C,3,3,&A[0][0],&Gamma[0][0],b,b2,2,&binterpt[0][0]);CHKERRQ(ierr);
478b1c69cc3SEmil Constantinescu   }
479b1c69cc3SEmil Constantinescu 
480b1c69cc3SEmil Constantinescu   {
481b1c69cc3SEmil Constantinescu     const PetscReal
482b1c69cc3SEmil Constantinescu       A[4][4] = {{0,0,0,0},
483b1c69cc3SEmil Constantinescu                  {1./2.,0,0,0},
484b1c69cc3SEmil Constantinescu                  {1./2.,1./2.,0,0},
485b1c69cc3SEmil Constantinescu                  {1./6.,1./6.,1./6.,0}},
486b1c69cc3SEmil Constantinescu       Gamma[4][4] = {{1./2.,0,0,0},
487b1c69cc3SEmil Constantinescu                      {0.0,1./4.,0,0},
488b1c69cc3SEmil Constantinescu                      {-2.,-2./3.,2./3.,0},
489b1c69cc3SEmil Constantinescu                      {1./2.,5./36.,-2./9,0}},
490b1c69cc3SEmil Constantinescu       b[4]  = {1./6.,1./6.,1./6.,1./2.},
491b1c69cc3SEmil Constantinescu       b2[4] = {1./8.,3./4.,1./8.,0};
492c0cb691aSEmil Constantinescu     PetscReal binterpt[4][3];
493da80777bSKarl Rupp 
494c0cb691aSEmil Constantinescu     binterpt[0][0]=6.25;
495c0cb691aSEmil Constantinescu     binterpt[1][0]=-30.25;
496c0cb691aSEmil Constantinescu     binterpt[2][0]=1.75;
497c0cb691aSEmil Constantinescu     binterpt[3][0]=23.25;
498c0cb691aSEmil Constantinescu     binterpt[0][1]=-9.75;
499c0cb691aSEmil Constantinescu     binterpt[1][1]=58.75;
500c0cb691aSEmil Constantinescu     binterpt[2][1]=-3.25;
501c0cb691aSEmil Constantinescu     binterpt[3][1]=-45.75;
502c0cb691aSEmil Constantinescu     binterpt[0][2]=3.6666666666666666666666666666667;
503c0cb691aSEmil Constantinescu     binterpt[1][2]=-28.333333333333333333333333333333;
504c0cb691aSEmil Constantinescu     binterpt[2][2]=1.6666666666666666666666666666667;
505c0cb691aSEmil Constantinescu     binterpt[3][2]=23.;
506bbd56ea5SKarl Rupp 
507c0cb691aSEmil Constantinescu     ierr = TSRosWRegister(TSROSWLASSP3P4S2C,3,4,&A[0][0],&Gamma[0][0],b,b2,3,&binterpt[0][0]);CHKERRQ(ierr);
508b1c69cc3SEmil Constantinescu   }
509b1c69cc3SEmil Constantinescu 
510b1c69cc3SEmil Constantinescu   {
511b1c69cc3SEmil Constantinescu     const PetscReal
512b1c69cc3SEmil Constantinescu       A[4][4] = {{0,0,0,0},
513b1c69cc3SEmil Constantinescu                  {1./2.,0,0,0},
514b1c69cc3SEmil Constantinescu                  {1./2.,1./2.,0,0},
515b1c69cc3SEmil Constantinescu                  {1./6.,1./6.,1./6.,0}},
516b1c69cc3SEmil Constantinescu       Gamma[4][4] = {{1./2.,0,0,0},
517b1c69cc3SEmil Constantinescu                      {0.0,3./4.,0,0},
518b1c69cc3SEmil Constantinescu                      {-2./3.,-23./9.,2./9.,0},
519b1c69cc3SEmil Constantinescu                      {1./18.,65./108.,-2./27,0}},
520b1c69cc3SEmil Constantinescu       b[4]  = {1./6.,1./6.,1./6.,1./2.},
521b1c69cc3SEmil Constantinescu       b2[4] = {3./16.,10./16.,3./16.,0};
522c0cb691aSEmil Constantinescu     PetscReal binterpt[4][3];
523da80777bSKarl Rupp 
524c0cb691aSEmil Constantinescu     binterpt[0][0]=1.6911764705882352941176470588235;
525c0cb691aSEmil Constantinescu     binterpt[1][0]=3.6813725490196078431372549019608;
526c0cb691aSEmil Constantinescu     binterpt[2][0]=0.23039215686274509803921568627451;
527c0cb691aSEmil Constantinescu     binterpt[3][0]=-4.6029411764705882352941176470588;
528c0cb691aSEmil Constantinescu     binterpt[0][1]=-0.95588235294117647058823529411765;
529c0cb691aSEmil Constantinescu     binterpt[1][1]=-6.2401960784313725490196078431373;
530c0cb691aSEmil Constantinescu     binterpt[2][1]=-0.31862745098039215686274509803922;
531c0cb691aSEmil Constantinescu     binterpt[3][1]=7.5147058823529411764705882352941;
532c0cb691aSEmil Constantinescu     binterpt[0][2]=-0.56862745098039215686274509803922;
533c0cb691aSEmil Constantinescu     binterpt[1][2]=2.7254901960784313725490196078431;
534c0cb691aSEmil Constantinescu     binterpt[2][2]=0.25490196078431372549019607843137;
535c0cb691aSEmil Constantinescu     binterpt[3][2]=-2.4117647058823529411764705882353;
536bbd56ea5SKarl Rupp 
537c0cb691aSEmil Constantinescu     ierr = TSRosWRegister(TSROSWLLSSP3P4S2C,3,4,&A[0][0],&Gamma[0][0],b,b2,3,&binterpt[0][0]);CHKERRQ(ierr);
538b1c69cc3SEmil Constantinescu   }
539753f8adbSEmil Constantinescu 
540753f8adbSEmil Constantinescu   {
541753f8adbSEmil Constantinescu     PetscReal A[4][4],Gamma[4][4],b[4],b2[4];
5423ca35412SEmil Constantinescu     PetscReal binterpt[4][3];
543753f8adbSEmil Constantinescu 
544753f8adbSEmil Constantinescu     Gamma[0][0]=0.4358665215084589994160194475295062513822671686978816;
54505e8e825SJed Brown     Gamma[0][1]=0; Gamma[0][2]=0; Gamma[0][3]=0;
546753f8adbSEmil Constantinescu     Gamma[1][0]=-1.997527830934941248426324674704153457289527280554476;
547753f8adbSEmil Constantinescu     Gamma[1][1]=0.4358665215084589994160194475295062513822671686978816;
54805e8e825SJed Brown     Gamma[1][2]=0; Gamma[1][3]=0;
549753f8adbSEmil Constantinescu     Gamma[2][0]=-1.007948511795029620852002345345404191008352770119903;
550753f8adbSEmil Constantinescu     Gamma[2][1]=-0.004648958462629345562774289390054679806993396798458131;
551753f8adbSEmil Constantinescu     Gamma[2][2]=0.4358665215084589994160194475295062513822671686978816;
55205e8e825SJed Brown     Gamma[2][3]=0;
553753f8adbSEmil Constantinescu     Gamma[3][0]=-0.6685429734233467180451604600279552604364311322650783;
554753f8adbSEmil Constantinescu     Gamma[3][1]=0.6056625986449338476089525334450053439525178740492984;
555753f8adbSEmil Constantinescu     Gamma[3][2]=-0.9717899277217721234705114616271378792182450260943198;
556753f8adbSEmil Constantinescu     Gamma[3][3]=0;
557753f8adbSEmil Constantinescu 
55805e8e825SJed Brown     A[0][0]=0; A[0][1]=0; A[0][2]=0; A[0][3]=0;
559753f8adbSEmil Constantinescu     A[1][0]=0.8717330430169179988320388950590125027645343373957631;
56005e8e825SJed Brown     A[1][1]=0; A[1][2]=0; A[1][3]=0;
561753f8adbSEmil Constantinescu     A[2][0]=0.5275890119763004115618079766722914408876108660811028;
562753f8adbSEmil Constantinescu     A[2][1]=0.07241098802369958843819203208518599088698057726988732;
56305e8e825SJed Brown     A[2][2]=0; A[2][3]=0;
564753f8adbSEmil Constantinescu     A[3][0]=0.3990960076760701320627260685975778145384666450351314;
565753f8adbSEmil Constantinescu     A[3][1]=-0.4375576546135194437228463747348862825846903771419953;
566753f8adbSEmil Constantinescu     A[3][2]=1.038461646937449311660120300601880176655352737312713;
56705e8e825SJed Brown     A[3][3]=0;
568753f8adbSEmil Constantinescu 
569753f8adbSEmil Constantinescu     b[0]=0.1876410243467238251612921333138006734899663569186926;
570753f8adbSEmil Constantinescu     b[1]=-0.5952974735769549480478230473706443582188442040780541;
571753f8adbSEmil Constantinescu     b[2]=0.9717899277217721234705114616271378792182450260943198;
572753f8adbSEmil Constantinescu     b[3]=0.4358665215084589994160194475295062513822671686978816;
573753f8adbSEmil Constantinescu 
574753f8adbSEmil Constantinescu     b2[0]=0.2147402862233891404862383521089097657790734483804460;
575753f8adbSEmil Constantinescu     b2[1]=-0.4851622638849390928209050538171743017757490232519684;
576753f8adbSEmil Constantinescu     b2[2]=0.8687250025203875511662123688667549217531982787600080;
577753f8adbSEmil Constantinescu     b2[3]=0.4016969751411624011684543450940068201770721128357014;
578753f8adbSEmil Constantinescu 
5793ca35412SEmil Constantinescu     binterpt[0][0]=2.2565812720167954547104627844105;
5803ca35412SEmil Constantinescu     binterpt[1][0]=1.349166413351089573796243820819;
5813ca35412SEmil Constantinescu     binterpt[2][0]=-2.4695174540533503758652847586647;
5823ca35412SEmil Constantinescu     binterpt[3][0]=-0.13623023131453465264142184656474;
5833ca35412SEmil Constantinescu     binterpt[0][1]=-3.0826699111559187902922463354557;
5843ca35412SEmil Constantinescu     binterpt[1][1]=-2.4689115685996042534544925650515;
5853ca35412SEmil Constantinescu     binterpt[2][1]=5.7428279814696677152129332773553;
5863ca35412SEmil Constantinescu     binterpt[3][1]=-0.19124650171414467146619437684812;
5873ca35412SEmil Constantinescu     binterpt[0][2]=1.0137296634858471607430756831148;
5883ca35412SEmil Constantinescu     binterpt[1][2]=0.52444768167155973161042570784064;
5893ca35412SEmil Constantinescu     binterpt[2][2]=-2.3015205996945452158771370439586;
5903ca35412SEmil Constantinescu     binterpt[3][2]=0.76334325453713832352363565300308;
591f4aed992SEmil Constantinescu 
592f73f8d2cSSatish Balay     ierr = TSRosWRegister(TSROSWARK3,3,4,&A[0][0],&Gamma[0][0],b,b2,3,&binterpt[0][0]);CHKERRQ(ierr);
593753f8adbSEmil Constantinescu   }
59442faf41dSJed Brown   ierr = TSRosWRegisterRos4(TSROSWGRK4T,0.231,PETSC_DEFAULT,PETSC_DEFAULT,0,-0.1282612945269037e+01);CHKERRQ(ierr);
59542faf41dSJed Brown   ierr = TSRosWRegisterRos4(TSROSWSHAMP4,0.5,PETSC_DEFAULT,PETSC_DEFAULT,0,125./108.);CHKERRQ(ierr);
59642faf41dSJed Brown   ierr = TSRosWRegisterRos4(TSROSWVELDD4,0.22570811482256823492,PETSC_DEFAULT,PETSC_DEFAULT,0,-1.355958941201148);CHKERRQ(ierr);
59742faf41dSJed Brown   ierr = TSRosWRegisterRos4(TSROSW4L,0.57282,PETSC_DEFAULT,PETSC_DEFAULT,0,-1.093502252409163);CHKERRQ(ierr);
598e27a552bSJed Brown   PetscFunctionReturn(0);
599e27a552bSJed Brown }
600e27a552bSJed Brown 
601d5e6173cSPeter Brune 
602d5e6173cSPeter Brune 
603e27a552bSJed Brown #undef __FUNCT__
604e27a552bSJed Brown #define __FUNCT__ "TSRosWRegisterDestroy"
605e27a552bSJed Brown /*@C
606e27a552bSJed Brown    TSRosWRegisterDestroy - Frees the list of schemes that were registered by TSRosWRegister().
607e27a552bSJed Brown 
608e27a552bSJed Brown    Not Collective
609e27a552bSJed Brown 
610e27a552bSJed Brown    Level: advanced
611e27a552bSJed Brown 
612e27a552bSJed Brown .keywords: TSRosW, register, destroy
613e27a552bSJed Brown .seealso: TSRosWRegister(), TSRosWRegisterAll(), TSRosWRegisterDynamic()
614e27a552bSJed Brown @*/
615e27a552bSJed Brown PetscErrorCode TSRosWRegisterDestroy(void)
616e27a552bSJed Brown {
617e27a552bSJed Brown   PetscErrorCode  ierr;
61861692a83SJed Brown   RosWTableauLink link;
619e27a552bSJed Brown 
620e27a552bSJed Brown   PetscFunctionBegin;
62161692a83SJed Brown   while ((link = RosWTableauList)) {
62261692a83SJed Brown     RosWTableau t = &link->tab;
62361692a83SJed Brown     RosWTableauList = link->next;
62461692a83SJed Brown     ierr = PetscFree5(t->A,t->Gamma,t->b,t->ASum,t->GammaSum);CHKERRQ(ierr);
62543b21953SEmil Constantinescu     ierr = PetscFree5(t->At,t->bt,t->GammaInv,t->GammaZeroDiag,t->GammaExplicitCorr);CHKERRQ(ierr);
626fe7e6d57SJed Brown     ierr = PetscFree2(t->bembed,t->bembedt);CHKERRQ(ierr);
627f4aed992SEmil Constantinescu     ierr = PetscFree(t->binterpt);CHKERRQ(ierr);
628e27a552bSJed Brown     ierr = PetscFree(t->name);CHKERRQ(ierr);
629e27a552bSJed Brown     ierr = PetscFree(link);CHKERRQ(ierr);
630e27a552bSJed Brown   }
631e27a552bSJed Brown   TSRosWRegisterAllCalled = PETSC_FALSE;
632e27a552bSJed Brown   PetscFunctionReturn(0);
633e27a552bSJed Brown }
634e27a552bSJed Brown 
635e27a552bSJed Brown #undef __FUNCT__
636e27a552bSJed Brown #define __FUNCT__ "TSRosWInitializePackage"
637e27a552bSJed Brown /*@C
638e27a552bSJed Brown   TSRosWInitializePackage - This function initializes everything in the TSRosW package. It is called
639e27a552bSJed Brown   from PetscDLLibraryRegister() when using dynamic libraries, and on the first call to TSCreate_RosW()
640e27a552bSJed Brown   when using static libraries.
641e27a552bSJed Brown 
642e27a552bSJed Brown   Input Parameter:
6430298fd71SBarry Smith   path - The dynamic library path, or NULL
644e27a552bSJed Brown 
645e27a552bSJed Brown   Level: developer
646e27a552bSJed Brown 
647e27a552bSJed Brown .keywords: TS, TSRosW, initialize, package
648e27a552bSJed Brown .seealso: PetscInitialize()
649e27a552bSJed Brown @*/
650e27a552bSJed Brown PetscErrorCode TSRosWInitializePackage(const char path[])
651e27a552bSJed Brown {
652e27a552bSJed Brown   PetscErrorCode ierr;
653e27a552bSJed Brown 
654e27a552bSJed Brown   PetscFunctionBegin;
655e27a552bSJed Brown   if (TSRosWPackageInitialized) PetscFunctionReturn(0);
656e27a552bSJed Brown   TSRosWPackageInitialized = PETSC_TRUE;
657e27a552bSJed Brown   ierr = TSRosWRegisterAll();CHKERRQ(ierr);
658e27a552bSJed Brown   ierr = PetscRegisterFinalize(TSRosWFinalizePackage);CHKERRQ(ierr);
659e27a552bSJed Brown   PetscFunctionReturn(0);
660e27a552bSJed Brown }
661e27a552bSJed Brown 
662e27a552bSJed Brown #undef __FUNCT__
663e27a552bSJed Brown #define __FUNCT__ "TSRosWFinalizePackage"
664e27a552bSJed Brown /*@C
665e27a552bSJed Brown   TSRosWFinalizePackage - This function destroys everything in the TSRosW package. It is
666e27a552bSJed Brown   called from PetscFinalize().
667e27a552bSJed Brown 
668e27a552bSJed Brown   Level: developer
669e27a552bSJed Brown 
670e27a552bSJed Brown .keywords: Petsc, destroy, package
671e27a552bSJed Brown .seealso: PetscFinalize()
672e27a552bSJed Brown @*/
673e27a552bSJed Brown PetscErrorCode TSRosWFinalizePackage(void)
674e27a552bSJed Brown {
675e27a552bSJed Brown   PetscErrorCode ierr;
676e27a552bSJed Brown 
677e27a552bSJed Brown   PetscFunctionBegin;
678e27a552bSJed Brown   TSRosWPackageInitialized = PETSC_FALSE;
679e27a552bSJed Brown   ierr = TSRosWRegisterDestroy();CHKERRQ(ierr);
680e27a552bSJed Brown   PetscFunctionReturn(0);
681e27a552bSJed Brown }
682e27a552bSJed Brown 
683e27a552bSJed Brown #undef __FUNCT__
684e27a552bSJed Brown #define __FUNCT__ "TSRosWRegister"
685e27a552bSJed Brown /*@C
68661692a83SJed Brown    TSRosWRegister - register a Rosenbrock W scheme by providing the entries in the Butcher tableau and optionally embedded approximations and interpolation
687e27a552bSJed Brown 
688e27a552bSJed Brown    Not Collective, but the same schemes should be registered on all processes on which they will be used
689e27a552bSJed Brown 
690e27a552bSJed Brown    Input Parameters:
691e27a552bSJed Brown +  name - identifier for method
692e27a552bSJed Brown .  order - approximation order of method
693e27a552bSJed Brown .  s - number of stages, this is the dimension of the matrices below
69461692a83SJed Brown .  A - Table of propagated stage coefficients (dimension s*s, row-major), strictly lower triangular
69561692a83SJed Brown .  Gamma - Table of coefficients in implicit stage equations (dimension s*s, row-major), lower triangular with nonzero diagonal
696fe7e6d57SJed Brown .  b - Step completion table (dimension s)
6970298fd71SBarry Smith .  bembed - Step completion table for a scheme of order one less (dimension s, NULL if no embedded scheme is available)
698f4aed992SEmil Constantinescu .  pinterp - Order of the interpolation scheme, equal to the number of columns of binterpt
69942faf41dSJed Brown -  binterpt - Coefficients of the interpolation formula (dimension s*pinterp)
700e27a552bSJed Brown 
701e27a552bSJed Brown    Notes:
70261692a83SJed Brown    Several Rosenbrock W methods are provided, this function is only needed to create new methods.
703e27a552bSJed Brown 
704e27a552bSJed Brown    Level: advanced
705e27a552bSJed Brown 
706e27a552bSJed Brown .keywords: TS, register
707e27a552bSJed Brown 
708e27a552bSJed Brown .seealso: TSRosW
709e27a552bSJed Brown @*/
710f9c1d6abSBarry Smith PetscErrorCode TSRosWRegister(TSRosWType name,PetscInt order,PetscInt s,const PetscReal A[],const PetscReal Gamma[],const PetscReal b[],const PetscReal bembed[],
711f4aed992SEmil Constantinescu                               PetscInt pinterp,const PetscReal binterpt[])
712e27a552bSJed Brown {
713e27a552bSJed Brown   PetscErrorCode  ierr;
71461692a83SJed Brown   RosWTableauLink link;
71561692a83SJed Brown   RosWTableau     t;
71661692a83SJed Brown   PetscInt        i,j,k;
71761692a83SJed Brown   PetscScalar     *GammaInv;
718e27a552bSJed Brown 
719e27a552bSJed Brown   PetscFunctionBegin;
720fe7e6d57SJed Brown   PetscValidCharPointer(name,1);
721fe7e6d57SJed Brown   PetscValidPointer(A,4);
722fe7e6d57SJed Brown   PetscValidPointer(Gamma,5);
723fe7e6d57SJed Brown   PetscValidPointer(b,6);
724fe7e6d57SJed Brown   if (bembed) PetscValidPointer(bembed,7);
725fe7e6d57SJed Brown 
726e27a552bSJed Brown   ierr     = PetscMalloc(sizeof(*link),&link);CHKERRQ(ierr);
727e27a552bSJed Brown   ierr     = PetscMemzero(link,sizeof(*link));CHKERRQ(ierr);
728e27a552bSJed Brown   t        = &link->tab;
729e27a552bSJed Brown   ierr     = PetscStrallocpy(name,&t->name);CHKERRQ(ierr);
730e27a552bSJed Brown   t->order = order;
731e27a552bSJed Brown   t->s     = s;
73261692a83SJed Brown   ierr     = PetscMalloc5(s*s,PetscReal,&t->A,s*s,PetscReal,&t->Gamma,s,PetscReal,&t->b,s,PetscReal,&t->ASum,s,PetscReal,&t->GammaSum);CHKERRQ(ierr);
73343b21953SEmil Constantinescu   ierr     = PetscMalloc5(s*s,PetscReal,&t->At,s,PetscReal,&t->bt,s*s,PetscReal,&t->GammaInv,s,PetscBool,&t->GammaZeroDiag,s*s,PetscReal,&t->GammaExplicitCorr);CHKERRQ(ierr);
734e27a552bSJed Brown   ierr     = PetscMemcpy(t->A,A,s*s*sizeof(A[0]));CHKERRQ(ierr);
73561692a83SJed Brown   ierr     = PetscMemcpy(t->Gamma,Gamma,s*s*sizeof(Gamma[0]));CHKERRQ(ierr);
73643b21953SEmil Constantinescu   ierr     = PetscMemcpy(t->GammaExplicitCorr,Gamma,s*s*sizeof(Gamma[0]));CHKERRQ(ierr);
73761692a83SJed Brown   ierr     = PetscMemcpy(t->b,b,s*sizeof(b[0]));CHKERRQ(ierr);
738fe7e6d57SJed Brown   if (bembed) {
739fe7e6d57SJed Brown     ierr = PetscMalloc2(s,PetscReal,&t->bembed,s,PetscReal,&t->bembedt);CHKERRQ(ierr);
740fe7e6d57SJed Brown     ierr = PetscMemcpy(t->bembed,bembed,s*sizeof(bembed[0]));CHKERRQ(ierr);
741fe7e6d57SJed Brown   }
74261692a83SJed Brown   for (i=0; i<s; i++) {
74361692a83SJed Brown     t->ASum[i]     = 0;
74461692a83SJed Brown     t->GammaSum[i] = 0;
74561692a83SJed Brown     for (j=0; j<s; j++) {
74661692a83SJed Brown       t->ASum[i]     += A[i*s+j];
747fe7e6d57SJed Brown       t->GammaSum[i] += Gamma[i*s+j];
74861692a83SJed Brown     }
74961692a83SJed Brown   }
75061692a83SJed Brown   ierr = PetscMalloc(s*s*sizeof(PetscScalar),&GammaInv);CHKERRQ(ierr); /* Need to use Scalar for inverse, then convert back to Real */
75161692a83SJed Brown   for (i=0; i<s*s; i++) GammaInv[i] = Gamma[i];
752fd96d5b0SEmil Constantinescu   for (i=0; i<s; i++) {
753fd96d5b0SEmil Constantinescu     if (Gamma[i*s+i] == 0.0) {
754fd96d5b0SEmil Constantinescu       GammaInv[i*s+i] = 1.0;
755c17803e7SJed Brown       t->GammaZeroDiag[i] = PETSC_TRUE;
756fd96d5b0SEmil Constantinescu     } else {
757c17803e7SJed Brown       t->GammaZeroDiag[i] = PETSC_FALSE;
758fd96d5b0SEmil Constantinescu     }
759fd96d5b0SEmil Constantinescu   }
760fd96d5b0SEmil Constantinescu 
76161692a83SJed Brown   switch (s) {
76261692a83SJed Brown   case 1: GammaInv[0] = 1./GammaInv[0]; break;
76396b95a6bSBarry Smith   case 2: ierr = PetscKernel_A_gets_inverse_A_2(GammaInv,0);CHKERRQ(ierr); break;
76496b95a6bSBarry Smith   case 3: ierr = PetscKernel_A_gets_inverse_A_3(GammaInv,0);CHKERRQ(ierr); break;
76596b95a6bSBarry Smith   case 4: ierr = PetscKernel_A_gets_inverse_A_4(GammaInv,0);CHKERRQ(ierr); break;
76661692a83SJed Brown   case 5: {
76761692a83SJed Brown     PetscInt  ipvt5[5];
76861692a83SJed Brown     MatScalar work5[5*5];
76996b95a6bSBarry Smith     ierr = PetscKernel_A_gets_inverse_A_5(GammaInv,ipvt5,work5,0);CHKERRQ(ierr); break;
77061692a83SJed Brown   }
77196b95a6bSBarry Smith   case 6: ierr = PetscKernel_A_gets_inverse_A_6(GammaInv,0);CHKERRQ(ierr); break;
77296b95a6bSBarry Smith   case 7: ierr = PetscKernel_A_gets_inverse_A_7(GammaInv,0);CHKERRQ(ierr); break;
77361692a83SJed Brown   default: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented for %D stages",s);
77461692a83SJed Brown   }
77561692a83SJed Brown   for (i=0; i<s*s; i++) t->GammaInv[i] = PetscRealPart(GammaInv[i]);
77661692a83SJed Brown   ierr = PetscFree(GammaInv);CHKERRQ(ierr);
77743b21953SEmil Constantinescu 
77843b21953SEmil Constantinescu   for (i=0; i<s; i++) {
77943b21953SEmil Constantinescu     for (k=0; k<i+1; k++) {
78043b21953SEmil Constantinescu       t->GammaExplicitCorr[i*s+k]=(t->GammaExplicitCorr[i*s+k])*(t->GammaInv[k*s+k]);
78143b21953SEmil Constantinescu       for (j=k+1; j<i+1; j++) {
78243b21953SEmil Constantinescu         t->GammaExplicitCorr[i*s+k]+=(t->GammaExplicitCorr[i*s+j])*(t->GammaInv[j*s+k]);
78343b21953SEmil Constantinescu       }
78443b21953SEmil Constantinescu     }
78543b21953SEmil Constantinescu   }
78643b21953SEmil Constantinescu 
78761692a83SJed Brown   for (i=0; i<s; i++) {
78861692a83SJed Brown     for (j=0; j<s; j++) {
78961692a83SJed Brown       t->At[i*s+j] = 0;
79061692a83SJed Brown       for (k=0; k<s; k++) {
79161692a83SJed Brown         t->At[i*s+j] += t->A[i*s+k] * t->GammaInv[k*s+j];
79261692a83SJed Brown       }
79361692a83SJed Brown     }
79461692a83SJed Brown     t->bt[i] = 0;
79561692a83SJed Brown     for (j=0; j<s; j++) {
79661692a83SJed Brown       t->bt[i] += t->b[j] * t->GammaInv[j*s+i];
79761692a83SJed Brown     }
798fe7e6d57SJed Brown     if (bembed) {
799fe7e6d57SJed Brown       t->bembedt[i] = 0;
800fe7e6d57SJed Brown       for (j=0; j<s; j++) {
801fe7e6d57SJed Brown         t->bembedt[i] += t->bembed[j] * t->GammaInv[j*s+i];
802fe7e6d57SJed Brown       }
803fe7e6d57SJed Brown     }
80461692a83SJed Brown   }
8058d59e960SJed Brown   t->ccfl = 1.0;                /* Fix this */
8068d59e960SJed Brown 
807f4aed992SEmil Constantinescu   t->pinterp = pinterp;
8083ca35412SEmil Constantinescu   ierr = PetscMalloc(s*pinterp*sizeof(binterpt[0]),&t->binterpt);CHKERRQ(ierr);
8093ca35412SEmil Constantinescu   ierr = PetscMemcpy(t->binterpt,binterpt,s*pinterp*sizeof(binterpt[0]));CHKERRQ(ierr);
81061692a83SJed Brown   link->next = RosWTableauList;
81161692a83SJed Brown   RosWTableauList = link;
812e27a552bSJed Brown   PetscFunctionReturn(0);
813e27a552bSJed Brown }
814e27a552bSJed Brown 
815e27a552bSJed Brown #undef __FUNCT__
81642faf41dSJed Brown #define __FUNCT__ "TSRosWRegisterRos4"
81742faf41dSJed Brown /*@C
81842faf41dSJed Brown    TSRosWRegisterRos4 - register a fourth order Rosenbrock scheme by providing paramter choices
81942faf41dSJed Brown 
82042faf41dSJed Brown    Not Collective, but the same schemes should be registered on all processes on which they will be used
82142faf41dSJed Brown 
82242faf41dSJed Brown    Input Parameters:
82342faf41dSJed Brown +  name - identifier for method
82442faf41dSJed Brown .  gamma - leading coefficient (diagonal entry)
82542faf41dSJed Brown .  a2 - design parameter, see Table 7.2 of Hairer&Wanner
82642faf41dSJed Brown .  a3 - design parameter or PETSC_DEFAULT to satisfy one of the order five conditions (Eq 7.22)
82742faf41dSJed Brown .  b3 - design parameter, see Table 7.2 of Hairer&Wanner
82842faf41dSJed Brown .  beta43 - design parameter or PETSC_DEFAULT to use Equation 7.21 of Hairer&Wanner
82942faf41dSJed Brown .  e4 - design parameter for embedded method, see coefficient E4 in ros4.f code from Hairer
83042faf41dSJed Brown 
83142faf41dSJed Brown    Notes:
83242faf41dSJed Brown    This routine encodes the design of fourth order Rosenbrock methods as described in Hairer and Wanner volume 2.
83342faf41dSJed Brown    It is used here to implement several methods from the book and can be used to experiment with new methods.
83442faf41dSJed Brown    It was written this way instead of by copying coefficients in order to provide better than double precision satisfaction of the order conditions.
83542faf41dSJed Brown 
83642faf41dSJed Brown    Level: developer
83742faf41dSJed Brown 
83842faf41dSJed Brown .keywords: TS, register
83942faf41dSJed Brown 
84042faf41dSJed Brown .seealso: TSRosW, TSRosWRegister()
84142faf41dSJed Brown @*/
84219fd82e9SBarry Smith PetscErrorCode TSRosWRegisterRos4(TSRosWType name,PetscReal gamma,PetscReal a2,PetscReal a3,PetscReal b3,PetscReal e4)
84342faf41dSJed Brown {
84442faf41dSJed Brown   PetscErrorCode ierr;
84542faf41dSJed Brown   /* Declare numeric constants so they can be quad precision without being truncated at double */
84642faf41dSJed Brown   const PetscReal one = 1,two = 2,three = 3,four = 4,five = 5,six = 6,eight = 8,twelve = 12,twenty = 20,twentyfour = 24,
84742faf41dSJed Brown     p32 = one/six - gamma + gamma*gamma,
84842faf41dSJed Brown     p42 = one/eight - gamma/three,
84942faf41dSJed Brown     p43 = one/twelve - gamma/three,
85042faf41dSJed Brown     p44 = one/twentyfour - gamma/two + three/two*gamma*gamma - gamma*gamma*gamma,
85142faf41dSJed Brown     p56 = one/twenty - gamma/four;
85242faf41dSJed Brown   PetscReal   a4,a32,a42,a43,b1,b2,b4,beta2p,beta3p,beta4p,beta32,beta42,beta43,beta32beta2p,beta4jbetajp;
85342faf41dSJed Brown   PetscReal   A[4][4],Gamma[4][4],b[4],bm[4];
85442faf41dSJed Brown   PetscScalar M[3][3],rhs[3];
85542faf41dSJed Brown 
85642faf41dSJed Brown   PetscFunctionBegin;
85742faf41dSJed Brown   /* Step 1: choose Gamma (input) */
85842faf41dSJed Brown   /* Step 2: choose a2,a3,a4; b1,b2,b3,b4 to satisfy order conditions */
85942faf41dSJed Brown   if (a3 == PETSC_DEFAULT) a3 = (one/five - a2/four)/(one/four - a2/three); /* Eq 7.22 */
86042faf41dSJed Brown   a4 = a3;                                                  /* consequence of 7.20 */
86142faf41dSJed Brown 
86242faf41dSJed Brown   /* Solve order conditions 7.15a, 7.15c, 7.15e */
86342faf41dSJed Brown   M[0][0] = one; M[0][1] = one;      M[0][2] = one;      /* 7.15a */
86442faf41dSJed Brown   M[1][0] = 0.0; M[1][1] = a2*a2;    M[1][2] = a4*a4;    /* 7.15c */
86542faf41dSJed Brown   M[2][0] = 0.0; M[2][1] = a2*a2*a2; M[2][2] = a4*a4*a4; /* 7.15e */
86642faf41dSJed Brown   rhs[0]  = one - b3;
86742faf41dSJed Brown   rhs[1]  = one/three - a3*a3*b3;
86842faf41dSJed Brown   rhs[2]  = one/four - a3*a3*a3*b3;
86942faf41dSJed Brown   ierr    = PetscKernel_A_gets_inverse_A_3(&M[0][0],0);CHKERRQ(ierr);
87042faf41dSJed Brown   b1      = PetscRealPart(M[0][0]*rhs[0] + M[0][1]*rhs[1] + M[0][2]*rhs[2]);
87142faf41dSJed Brown   b2      = PetscRealPart(M[1][0]*rhs[0] + M[1][1]*rhs[1] + M[1][2]*rhs[2]);
87242faf41dSJed Brown   b4      = PetscRealPart(M[2][0]*rhs[0] + M[2][1]*rhs[1] + M[2][2]*rhs[2]);
87342faf41dSJed Brown 
87442faf41dSJed Brown   /* Step 3 */
87542faf41dSJed Brown   beta43       = (p56 - a2*p43) / (b4*a3*a3*(a3 - a2)); /* 7.21 */
87642faf41dSJed Brown   beta32beta2p =  p44 / (b4*beta43);                    /* 7.15h */
87742faf41dSJed Brown   beta4jbetajp = (p32 - b3*beta32beta2p) / b4;
87842faf41dSJed Brown   M[0][0]      = b2;                                    M[0][1] = b3;                 M[0][2] = b4;
87942faf41dSJed Brown   M[1][0]      = a4*a4*beta32beta2p-a3*a3*beta4jbetajp; M[1][1] = a2*a2*beta4jbetajp; M[1][2] = -a2*a2*beta32beta2p;
88042faf41dSJed Brown   M[2][0]      = b4*beta43*a3*a3-p43;                   M[2][1] = -b4*beta43*a2*a2;   M[2][2] = 0;
88142faf41dSJed Brown   rhs[0]       = one/two - gamma; rhs[1] = 0; rhs[2] = -a2*a2*p32;
88242faf41dSJed Brown   ierr         = PetscKernel_A_gets_inverse_A_3(&M[0][0],0);CHKERRQ(ierr);
88342faf41dSJed Brown   beta2p       = PetscRealPart(M[0][0]*rhs[0] + M[0][1]*rhs[1] + M[0][2]*rhs[2]);
88442faf41dSJed Brown   beta3p       = PetscRealPart(M[1][0]*rhs[0] + M[1][1]*rhs[1] + M[1][2]*rhs[2]);
88542faf41dSJed Brown   beta4p       = PetscRealPart(M[2][0]*rhs[0] + M[2][1]*rhs[1] + M[2][2]*rhs[2]);
88642faf41dSJed Brown 
88742faf41dSJed Brown   /* Step 4: back-substitute */
88842faf41dSJed Brown   beta32 = beta32beta2p / beta2p;
88942faf41dSJed Brown   beta42 = (beta4jbetajp - beta43*beta3p) / beta2p;
89042faf41dSJed Brown 
89142faf41dSJed Brown   /* Step 5: 7.15f and 7.20, then 7.16 */
89242faf41dSJed Brown   a43 = 0;
89342faf41dSJed Brown   a32 = p42 / (b3*a3*beta2p + b4*a4*beta2p);
89442faf41dSJed Brown   a42 = a32;
89542faf41dSJed Brown 
89642faf41dSJed Brown   A[0][0]     = 0;          A[0][1] = 0;   A[0][2] = 0;   A[0][3] = 0;
89742faf41dSJed Brown   A[1][0]     = a2;         A[1][1] = 0;   A[1][2] = 0;   A[1][3] = 0;
89842faf41dSJed Brown   A[2][0]     = a3-a32;     A[2][1] = a32; A[2][2] = 0;   A[2][3] = 0;
89942faf41dSJed Brown   A[3][0]     = a4-a43-a42; A[3][1] = a42; A[3][2] = a43; A[3][3] = 0;
90042faf41dSJed Brown   Gamma[0][0] = gamma;                        Gamma[0][1] = 0;              Gamma[0][2] = 0;              Gamma[0][3] = 0;
90142faf41dSJed Brown   Gamma[1][0] = beta2p-A[1][0];               Gamma[1][1] = gamma;          Gamma[1][2] = 0;              Gamma[1][3] = 0;
90242faf41dSJed Brown   Gamma[2][0] = beta3p-beta32-A[2][0];        Gamma[2][1] = beta32-A[2][1]; Gamma[2][2] = gamma;          Gamma[2][3] = 0;
90342faf41dSJed 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;
90442faf41dSJed Brown   b[0] = b1; b[1] = b2; b[2] = b3; b[3] = b4;
90542faf41dSJed Brown 
90642faf41dSJed Brown   /* Construct embedded formula using given e4. We are solving Equation 7.18. */
90742faf41dSJed Brown   bm[3] = b[3] - e4*gamma;                                          /* using definition of E4 */
90842faf41dSJed Brown   bm[2] = (p32 - beta4jbetajp*bm[3]) / (beta32*beta2p);             /* fourth row of 7.18 */
90942faf41dSJed Brown   bm[1] = (one/two - gamma - beta3p*bm[2] - beta4p*bm[3]) / beta2p; /* second row */
91042faf41dSJed Brown   bm[0] = one - bm[1] - bm[2] - bm[3];                              /* first row */
91142faf41dSJed Brown 
91242faf41dSJed Brown   {
91342faf41dSJed Brown     const PetscReal misfit = a2*a2*bm[1] + a3*a3*bm[2] + a4*a4*bm[3] - one/three;
91442faf41dSJed Brown     if (PetscAbs(misfit) > PETSC_SMALL) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Assumptions violated, could not construct a third order embedded method");
91542faf41dSJed Brown   }
9160298fd71SBarry Smith   ierr = TSRosWRegister(name,4,4,&A[0][0],&Gamma[0][0],b,bm,0,NULL);CHKERRQ(ierr);
91742faf41dSJed Brown   PetscFunctionReturn(0);
91842faf41dSJed Brown }
91942faf41dSJed Brown 
92042faf41dSJed Brown #undef __FUNCT__
9211c3436cfSJed Brown #define __FUNCT__ "TSEvaluateStep_RosW"
9221c3436cfSJed Brown /*
9231c3436cfSJed Brown  The step completion formula is
9241c3436cfSJed Brown 
9251c3436cfSJed Brown  x1 = x0 + b^T Y
9261c3436cfSJed Brown 
9271c3436cfSJed Brown  where Y is the multi-vector of stages corrections. This function can be called before or after ts->vec_sol has been
9281c3436cfSJed Brown  updated. Suppose we have a completion formula b and an embedded formula be of different order. We can write
9291c3436cfSJed Brown 
9301c3436cfSJed Brown  x1e = x0 + be^T Y
9311c3436cfSJed Brown      = x1 - b^T Y + be^T Y
9321c3436cfSJed Brown      = x1 + (be - b)^T Y
9331c3436cfSJed Brown 
9341c3436cfSJed Brown  so we can evaluate the method of different order even after the step has been optimistically completed.
9351c3436cfSJed Brown */
936f9c1d6abSBarry Smith static PetscErrorCode TSEvaluateStep_RosW(TS ts,PetscInt order,Vec U,PetscBool *done)
9371c3436cfSJed Brown {
9381c3436cfSJed Brown   TS_RosW        *ros = (TS_RosW*)ts->data;
9391c3436cfSJed Brown   RosWTableau    tab  = ros->tableau;
9401c3436cfSJed Brown   PetscScalar    *w   = ros->work;
9411c3436cfSJed Brown   PetscInt       i;
9421c3436cfSJed Brown   PetscErrorCode ierr;
9431c3436cfSJed Brown 
9441c3436cfSJed Brown   PetscFunctionBegin;
9451c3436cfSJed Brown   if (order == tab->order) {
946108c343cSJed Brown     if (ros->status == TS_STEP_INCOMPLETE) { /* Use standard completion formula */
947f9c1d6abSBarry Smith       ierr = VecCopy(ts->vec_sol,U);CHKERRQ(ierr);
948de19f811SJed Brown       for (i=0; i<tab->s; i++) w[i] = tab->bt[i];
949f9c1d6abSBarry Smith       ierr = VecMAXPY(U,tab->s,w,ros->Y);CHKERRQ(ierr);
950f9c1d6abSBarry Smith     } else {ierr = VecCopy(ts->vec_sol,U);CHKERRQ(ierr);}
9511c3436cfSJed Brown     if (done) *done = PETSC_TRUE;
9521c3436cfSJed Brown     PetscFunctionReturn(0);
9531c3436cfSJed Brown   } else if (order == tab->order-1) {
9541c3436cfSJed Brown     if (!tab->bembedt) goto unavailable;
955108c343cSJed Brown     if (ros->status == TS_STEP_INCOMPLETE) { /* Use embedded completion formula */
956f9c1d6abSBarry Smith       ierr = VecCopy(ts->vec_sol,U);CHKERRQ(ierr);
957de19f811SJed Brown       for (i=0; i<tab->s; i++) w[i] = tab->bembedt[i];
958f9c1d6abSBarry Smith       ierr = VecMAXPY(U,tab->s,w,ros->Y);CHKERRQ(ierr);
959108c343cSJed Brown     } else {                    /* Use rollback-and-recomplete formula (bembedt - bt) */
960108c343cSJed Brown       for (i=0; i<tab->s; i++) w[i] = tab->bembedt[i] - tab->bt[i];
961f9c1d6abSBarry Smith       ierr = VecCopy(ts->vec_sol,U);CHKERRQ(ierr);
962f9c1d6abSBarry Smith       ierr = VecMAXPY(U,tab->s,w,ros->Y);CHKERRQ(ierr);
9631c3436cfSJed Brown     }
9641c3436cfSJed Brown     if (done) *done = PETSC_TRUE;
9651c3436cfSJed Brown     PetscFunctionReturn(0);
9661c3436cfSJed Brown   }
9671c3436cfSJed Brown   unavailable:
9681c3436cfSJed Brown   if (done) *done = PETSC_FALSE;
969*ce94432eSBarry Smith   else SETERRQ3(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Rosenbrock-W '%s' of order %D cannot evaluate step at order %D",tab->name,tab->order,order);
9701c3436cfSJed Brown   PetscFunctionReturn(0);
9711c3436cfSJed Brown }
9721c3436cfSJed Brown 
9731c3436cfSJed Brown #undef __FUNCT__
974e27a552bSJed Brown #define __FUNCT__ "TSStep_RosW"
975e27a552bSJed Brown static PetscErrorCode TSStep_RosW(TS ts)
976e27a552bSJed Brown {
97761692a83SJed Brown   TS_RosW         *ros = (TS_RosW*)ts->data;
97861692a83SJed Brown   RosWTableau     tab  = ros->tableau;
979e27a552bSJed Brown   const PetscInt  s    = tab->s;
9801c3436cfSJed Brown   const PetscReal *At  = tab->At,*Gamma = tab->Gamma,*ASum = tab->ASum,*GammaInv = tab->GammaInv;
9810feba352SEmil Constantinescu   const PetscReal *GammaExplicitCorr = tab->GammaExplicitCorr;
982c17803e7SJed Brown   const PetscBool *GammaZeroDiag = tab->GammaZeroDiag;
98361692a83SJed Brown   PetscScalar     *w   = ros->work;
9847d4bf2deSEmil Constantinescu   Vec             *Y   = ros->Y,Ydot = ros->Ydot,Zdot = ros->Zdot,Zstage = ros->Zstage;
985e27a552bSJed Brown   SNES            snes;
9861c3436cfSJed Brown   TSAdapt         adapt;
9871c3436cfSJed Brown   PetscInt        i,j,its,lits,reject,next_scheme;
988cdbf8f93SLisandro Dalcin   PetscReal       next_time_step;
9891c3436cfSJed Brown   PetscBool       accept;
990e27a552bSJed Brown   PetscErrorCode  ierr;
9910feba352SEmil Constantinescu   MatStructure    str;
992e27a552bSJed Brown 
993e27a552bSJed Brown   PetscFunctionBegin;
994e27a552bSJed Brown   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
995cdbf8f93SLisandro Dalcin   next_time_step = ts->time_step;
9961c3436cfSJed Brown   accept         = PETSC_TRUE;
997108c343cSJed Brown   ros->status    = TS_STEP_INCOMPLETE;
998e27a552bSJed Brown 
99997335746SJed Brown   for (reject=0; reject<ts->max_reject && !ts->reason; reject++,ts->reject++) {
10001c3436cfSJed Brown     const PetscReal h = ts->time_step;
1001b8123daeSJed Brown     ierr = TSPreStep(ts);CHKERRQ(ierr);
10023ca35412SEmil Constantinescu     ierr = VecCopy(ts->vec_sol,ros->VecSolPrev);CHKERRQ(ierr); /*move this at the end*/
1003e27a552bSJed Brown     for (i=0; i<s; i++) {
10041c3436cfSJed Brown       ros->stage_time = ts->ptime + h*ASum[i];
1005b8123daeSJed Brown       ierr = TSPreStage(ts,ros->stage_time);CHKERRQ(ierr);
1006c17803e7SJed Brown       if (GammaZeroDiag[i]) {
1007c17803e7SJed Brown         ros->stage_explicit = PETSC_TRUE;
1008b296d7d5SJed Brown         ros->scoeff         = 1.;
1009c17803e7SJed Brown       } else {
1010c17803e7SJed Brown         ros->stage_explicit = PETSC_FALSE;
1011b296d7d5SJed Brown         ros->scoeff         = 1./Gamma[i*s+i];
1012fd96d5b0SEmil Constantinescu       }
101361692a83SJed Brown 
101461692a83SJed Brown       ierr = VecCopy(ts->vec_sol,Zstage);CHKERRQ(ierr);
1015de19f811SJed Brown       for (j=0; j<i; j++) w[j] = At[i*s+j];
1016de19f811SJed Brown       ierr = VecMAXPY(Zstage,i,w,Y);CHKERRQ(ierr);
101761692a83SJed Brown 
101861692a83SJed Brown       for (j=0; j<i; j++) w[j] = 1./h * GammaInv[i*s+j];
101961692a83SJed Brown       ierr = VecZeroEntries(Zdot);CHKERRQ(ierr);
102061692a83SJed Brown       ierr = VecMAXPY(Zdot,i,w,Y);CHKERRQ(ierr);
102161692a83SJed Brown 
1022e27a552bSJed Brown       /* Initial guess taken from last stage */
102361692a83SJed Brown       ierr = VecZeroEntries(Y[i]);CHKERRQ(ierr);
102461692a83SJed Brown 
10257d4bf2deSEmil Constantinescu       if (!ros->stage_explicit) {
102661692a83SJed Brown         if (!ros->recompute_jacobian && !i) {
102761692a83SJed Brown           ierr = SNESSetLagJacobian(snes,-2);CHKERRQ(ierr); /* Recompute the Jacobian on this solve, but not again */
102861692a83SJed Brown         }
10290298fd71SBarry Smith         ierr = SNESSolve(snes,NULL,Y[i]);CHKERRQ(ierr);
1030e27a552bSJed Brown         ierr = SNESGetIterationNumber(snes,&its);CHKERRQ(ierr);
1031e27a552bSJed Brown         ierr = SNESGetLinearSolveIterations(snes,&lits);CHKERRQ(ierr);
10325ef26d82SJed Brown         ts->snes_its += its; ts->ksp_its += lits;
1033ad6bc421SBarry Smith         ierr = TSGetTSAdapt(ts,&adapt);CHKERRQ(ierr);
103497335746SJed Brown         ierr = TSAdaptCheckStage(adapt,ts,&accept);CHKERRQ(ierr);
103597335746SJed Brown         if (!accept) goto reject_step;
10367d4bf2deSEmil Constantinescu       } else {
10371ce71dffSSatish Balay         Mat J,Jp;
10380feba352SEmil Constantinescu         ierr = VecZeroEntries(Ydot);CHKERRQ(ierr); /* Evaluate Y[i]=G(t,Ydot=0,Zstage) */
10390feba352SEmil Constantinescu         ierr = TSComputeIFunction(ts,ros->stage_time,Zstage,Ydot,Y[i],PETSC_FALSE);CHKERRQ(ierr);
104022d28d08SBarry Smith         ierr = VecScale(Y[i],-1.0);CHKERRQ(ierr);
10410feba352SEmil Constantinescu         ierr = VecAXPY(Y[i],-1.0,Zdot);CHKERRQ(ierr); /*Y[i]=F(Zstage)-Zdot[=GammaInv*Y]*/
10420feba352SEmil Constantinescu 
10430feba352SEmil Constantinescu         ierr = VecZeroEntries(Zstage);CHKERRQ(ierr); /* Zstage = GammaExplicitCorr[i,j] * Y[j] */
10440feba352SEmil Constantinescu         for (j=0; j<i; j++) w[j] = GammaExplicitCorr[i*s+j];
10450feba352SEmil Constantinescu         ierr = VecMAXPY(Zstage,i,w,Y);CHKERRQ(ierr);
10460feba352SEmil Constantinescu         /*Y[i] += Y[i] + Jac*Zstage[=Jac*GammaExplicitCorr[i,j] * Y[j]] */
10470feba352SEmil Constantinescu         str  = SAME_NONZERO_PATTERN;
10480298fd71SBarry Smith         ierr = TSGetIJacobian(ts,&J,&Jp,NULL,NULL);CHKERRQ(ierr);
10490feba352SEmil Constantinescu         ierr = TSComputeIJacobian(ts,ros->stage_time,ts->vec_sol,Ydot,0,&J,&Jp,&str,PETSC_FALSE);CHKERRQ(ierr);
105022d28d08SBarry Smith         ierr = MatMult(J,Zstage,Zdot);CHKERRQ(ierr);
10510feba352SEmil Constantinescu 
10520feba352SEmil Constantinescu         ierr = VecAXPY(Y[i],-1.0,Zdot);CHKERRQ(ierr);
10530feba352SEmil Constantinescu         ierr = VecScale(Y[i],h);
10545ef26d82SJed Brown         ts->ksp_its += 1;
10557d4bf2deSEmil Constantinescu       }
1056e27a552bSJed Brown     }
10570298fd71SBarry Smith     ierr = TSEvaluateStep(ts,tab->order,ts->vec_sol,NULL);CHKERRQ(ierr);
1058108c343cSJed Brown     ros->status = TS_STEP_PENDING;
1059e27a552bSJed Brown 
10601c3436cfSJed Brown     /* Register only the current method as a candidate because we're not supporting multiple candidates yet. */
1061ad6bc421SBarry Smith     ierr = TSGetTSAdapt(ts,&adapt);CHKERRQ(ierr);
10621c3436cfSJed Brown     ierr = TSAdaptCandidatesClear(adapt);CHKERRQ(ierr);
10638d59e960SJed Brown     ierr = TSAdaptCandidateAdd(adapt,tab->name,tab->order,1,tab->ccfl,1.*tab->s,PETSC_TRUE);CHKERRQ(ierr);
10641c3436cfSJed Brown     ierr = TSAdaptChoose(adapt,ts,ts->time_step,&next_scheme,&next_time_step,&accept);CHKERRQ(ierr);
10651c3436cfSJed Brown     if (accept) {
10661c3436cfSJed Brown       /* ignore next_scheme for now */
1067e27a552bSJed Brown       ts->ptime    += ts->time_step;
1068cdbf8f93SLisandro Dalcin       ts->time_step = next_time_step;
1069e27a552bSJed Brown       ts->steps++;
1070108c343cSJed Brown       ros->status = TS_STEP_COMPLETE;
10711c3436cfSJed Brown       break;
10721c3436cfSJed Brown     } else {                    /* Roll back the current step */
10731c3436cfSJed Brown       for (i=0; i<s; i++) w[i] = -tab->bt[i];
10741c3436cfSJed Brown       ierr = VecMAXPY(ts->vec_sol,s,w,Y);CHKERRQ(ierr);
10751c3436cfSJed Brown       ts->time_step = next_time_step;
1076108c343cSJed Brown       ros->status   = TS_STEP_INCOMPLETE;
10771c3436cfSJed Brown     }
1078476b6736SJed Brown reject_step: continue;
10791c3436cfSJed Brown   }
1080b2ce242eSJed Brown   if (ros->status != TS_STEP_COMPLETE && !ts->reason) ts->reason = TS_DIVERGED_STEP_REJECTED;
1081e27a552bSJed Brown   PetscFunctionReturn(0);
1082e27a552bSJed Brown }
1083e27a552bSJed Brown 
1084e27a552bSJed Brown #undef __FUNCT__
1085e27a552bSJed Brown #define __FUNCT__ "TSInterpolate_RosW"
1086f9c1d6abSBarry Smith static PetscErrorCode TSInterpolate_RosW(TS ts,PetscReal itime,Vec U)
1087e27a552bSJed Brown {
108861692a83SJed Brown   TS_RosW         *ros = (TS_RosW*)ts->data;
1089f4aed992SEmil Constantinescu   PetscInt        s    = ros->tableau->s,pinterp = ros->tableau->pinterp,i,j;
1090f4aed992SEmil Constantinescu   PetscReal       h;
1091f4aed992SEmil Constantinescu   PetscReal       tt,t;
1092f4aed992SEmil Constantinescu   PetscScalar     *bt;
1093f4aed992SEmil Constantinescu   const PetscReal *Bt = ros->tableau->binterpt;
1094f4aed992SEmil Constantinescu   PetscErrorCode  ierr;
1095f4aed992SEmil Constantinescu   const PetscReal *GammaInv = ros->tableau->GammaInv;
1096f4aed992SEmil Constantinescu   PetscScalar     *w        = ros->work;
1097f4aed992SEmil Constantinescu   Vec             *Y        = ros->Y;
1098e27a552bSJed Brown 
1099e27a552bSJed Brown   PetscFunctionBegin;
1100*ce94432eSBarry Smith   if (!Bt) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSRosW %s does not have an interpolation formula",ros->tableau->name);
1101f4aed992SEmil Constantinescu 
1102f4aed992SEmil Constantinescu   switch (ros->status) {
1103f4aed992SEmil Constantinescu   case TS_STEP_INCOMPLETE:
1104f4aed992SEmil Constantinescu   case TS_STEP_PENDING:
1105f4aed992SEmil Constantinescu     h = ts->time_step;
1106f4aed992SEmil Constantinescu     t = (itime - ts->ptime)/h;
1107f4aed992SEmil Constantinescu     break;
1108f4aed992SEmil Constantinescu   case TS_STEP_COMPLETE:
1109f4aed992SEmil Constantinescu     h = ts->time_step_prev;
1110f4aed992SEmil Constantinescu     t = (itime - ts->ptime)/h + 1; /* In the interval [0,1] */
1111f4aed992SEmil Constantinescu     break;
1112*ce94432eSBarry Smith   default: SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_PLIB,"Invalid TSStepStatus");
1113f4aed992SEmil Constantinescu   }
11143ca35412SEmil Constantinescu   ierr = PetscMalloc(s*sizeof(bt[0]),&bt);CHKERRQ(ierr);
1115f4aed992SEmil Constantinescu   for (i=0; i<s; i++) bt[i] = 0;
1116f4aed992SEmil Constantinescu   for (j=0,tt=t; j<pinterp; j++,tt*=t) {
1117f4aed992SEmil Constantinescu     for (i=0; i<s; i++) {
11183ca35412SEmil Constantinescu       bt[i] += Bt[i*pinterp+j] * tt;
1119f4aed992SEmil Constantinescu     }
1120f4aed992SEmil Constantinescu   }
1121f4aed992SEmil Constantinescu 
1122f4aed992SEmil Constantinescu   /* y(t+tt*h) = y(t) + Sum bt(tt) * GammaInv * Ydot */
1123f9c1d6abSBarry Smith   /*U<-0*/
1124f9c1d6abSBarry Smith   ierr = VecZeroEntries(U);CHKERRQ(ierr);
1125f4aed992SEmil Constantinescu 
1126f9c1d6abSBarry Smith   /*U<- Sum bt_i * GammaInv(i,1:i) * Y(1:i) */
11273ca35412SEmil Constantinescu   for (j=0; j<s; j++) w[j]=0;
11283ca35412SEmil Constantinescu   for (j=0; j<s; j++) {
11293ca35412SEmil Constantinescu     for (i=j; i<s; i++) {
11303ca35412SEmil Constantinescu       w[j] +=  bt[i]*GammaInv[i*s+j];
1131f4aed992SEmil Constantinescu     }
11323ca35412SEmil Constantinescu   }
1133f9c1d6abSBarry Smith   ierr = VecMAXPY(U,i,w,Y);CHKERRQ(ierr);
1134f4aed992SEmil Constantinescu 
1135f4aed992SEmil Constantinescu   /*X<-y(t) + X*/
1136f9c1d6abSBarry Smith   ierr = VecAXPY(U,1.0,ros->VecSolPrev);CHKERRQ(ierr);
1137f4aed992SEmil Constantinescu 
1138f4aed992SEmil Constantinescu   ierr = PetscFree(bt);CHKERRQ(ierr);
1139e27a552bSJed Brown   PetscFunctionReturn(0);
1140e27a552bSJed Brown }
1141e27a552bSJed Brown 
1142e27a552bSJed Brown /*------------------------------------------------------------*/
1143e27a552bSJed Brown #undef __FUNCT__
1144e27a552bSJed Brown #define __FUNCT__ "TSReset_RosW"
1145e27a552bSJed Brown static PetscErrorCode TSReset_RosW(TS ts)
1146e27a552bSJed Brown {
114761692a83SJed Brown   TS_RosW        *ros = (TS_RosW*)ts->data;
1148e27a552bSJed Brown   PetscInt       s;
1149e27a552bSJed Brown   PetscErrorCode ierr;
1150e27a552bSJed Brown 
1151e27a552bSJed Brown   PetscFunctionBegin;
115261692a83SJed Brown   if (!ros->tableau) PetscFunctionReturn(0);
115361692a83SJed Brown   s    = ros->tableau->s;
115461692a83SJed Brown   ierr = VecDestroyVecs(s,&ros->Y);CHKERRQ(ierr);
115561692a83SJed Brown   ierr = VecDestroy(&ros->Ydot);CHKERRQ(ierr);
115661692a83SJed Brown   ierr = VecDestroy(&ros->Ystage);CHKERRQ(ierr);
115761692a83SJed Brown   ierr = VecDestroy(&ros->Zdot);CHKERRQ(ierr);
115861692a83SJed Brown   ierr = VecDestroy(&ros->Zstage);CHKERRQ(ierr);
11593ca35412SEmil Constantinescu   ierr = VecDestroy(&ros->VecSolPrev);CHKERRQ(ierr);
116061692a83SJed Brown   ierr = PetscFree(ros->work);CHKERRQ(ierr);
1161e27a552bSJed Brown   PetscFunctionReturn(0);
1162e27a552bSJed Brown }
1163e27a552bSJed Brown 
1164e27a552bSJed Brown #undef __FUNCT__
1165e27a552bSJed Brown #define __FUNCT__ "TSDestroy_RosW"
1166e27a552bSJed Brown static PetscErrorCode TSDestroy_RosW(TS ts)
1167e27a552bSJed Brown {
1168e27a552bSJed Brown   PetscErrorCode ierr;
1169e27a552bSJed Brown 
1170e27a552bSJed Brown   PetscFunctionBegin;
1171e27a552bSJed Brown   ierr = TSReset_RosW(ts);CHKERRQ(ierr);
1172e27a552bSJed Brown   ierr = PetscFree(ts->data);CHKERRQ(ierr);
11730298fd71SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSRosWGetType_C","",NULL);CHKERRQ(ierr);
11740298fd71SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSRosWSetType_C","",NULL);CHKERRQ(ierr);
11750298fd71SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSRosWSetRecomputeJacobian_C","",NULL);CHKERRQ(ierr);
1176e27a552bSJed Brown   PetscFunctionReturn(0);
1177e27a552bSJed Brown }
1178e27a552bSJed Brown 
1179d5e6173cSPeter Brune 
1180d5e6173cSPeter Brune #undef __FUNCT__
1181d5e6173cSPeter Brune #define __FUNCT__ "TSRosWGetVecs"
1182d5e6173cSPeter Brune static PetscErrorCode TSRosWGetVecs(TS ts,DM dm,Vec *Ydot,Vec *Zdot,Vec *Ystage,Vec *Zstage)
1183d5e6173cSPeter Brune {
1184d5e6173cSPeter Brune   TS_RosW        *rw = (TS_RosW*)ts->data;
1185d5e6173cSPeter Brune   PetscErrorCode ierr;
1186d5e6173cSPeter Brune 
1187d5e6173cSPeter Brune   PetscFunctionBegin;
1188d5e6173cSPeter Brune   if (Ydot) {
1189d5e6173cSPeter Brune     if (dm && dm != ts->dm) {
1190d5e6173cSPeter Brune       ierr = DMGetNamedGlobalVector(dm,"TSRosW_Ydot",Ydot);CHKERRQ(ierr);
1191d5e6173cSPeter Brune     } else *Ydot = rw->Ydot;
1192d5e6173cSPeter Brune   }
1193d5e6173cSPeter Brune   if (Zdot) {
1194d5e6173cSPeter Brune     if (dm && dm != ts->dm) {
1195d5e6173cSPeter Brune       ierr = DMGetNamedGlobalVector(dm,"TSRosW_Zdot",Zdot);CHKERRQ(ierr);
1196d5e6173cSPeter Brune     } else *Zdot = rw->Zdot;
1197d5e6173cSPeter Brune   }
1198d5e6173cSPeter Brune   if (Ystage) {
1199d5e6173cSPeter Brune     if (dm && dm != ts->dm) {
1200d5e6173cSPeter Brune       ierr = DMGetNamedGlobalVector(dm,"TSRosW_Ystage",Ystage);CHKERRQ(ierr);
1201d5e6173cSPeter Brune     } else *Ystage = rw->Ystage;
1202d5e6173cSPeter Brune   }
1203d5e6173cSPeter Brune   if (Zstage) {
1204d5e6173cSPeter Brune     if (dm && dm != ts->dm) {
1205d5e6173cSPeter Brune       ierr = DMGetNamedGlobalVector(dm,"TSRosW_Zstage",Zstage);CHKERRQ(ierr);
1206d5e6173cSPeter Brune     } else *Zstage = rw->Zstage;
1207d5e6173cSPeter Brune   }
1208d5e6173cSPeter Brune   PetscFunctionReturn(0);
1209d5e6173cSPeter Brune }
1210d5e6173cSPeter Brune 
1211d5e6173cSPeter Brune 
1212d5e6173cSPeter Brune #undef __FUNCT__
1213d5e6173cSPeter Brune #define __FUNCT__ "TSRosWRestoreVecs"
1214d5e6173cSPeter Brune static PetscErrorCode TSRosWRestoreVecs(TS ts,DM dm,Vec *Ydot,Vec *Zdot, Vec *Ystage, Vec *Zstage)
1215d5e6173cSPeter Brune {
1216d5e6173cSPeter Brune   PetscErrorCode ierr;
1217d5e6173cSPeter Brune 
1218d5e6173cSPeter Brune   PetscFunctionBegin;
1219d5e6173cSPeter Brune   if (Ydot) {
1220d5e6173cSPeter Brune     if (dm && dm != ts->dm) {
1221d5e6173cSPeter Brune       ierr = DMRestoreNamedGlobalVector(dm,"TSRosW_Ydot",Ydot);CHKERRQ(ierr);
1222d5e6173cSPeter Brune     }
1223d5e6173cSPeter Brune   }
1224d5e6173cSPeter Brune   if (Zdot) {
1225d5e6173cSPeter Brune     if (dm && dm != ts->dm) {
1226d5e6173cSPeter Brune       ierr = DMRestoreNamedGlobalVector(dm,"TSRosW_Zdot",Zdot);CHKERRQ(ierr);
1227d5e6173cSPeter Brune     }
1228d5e6173cSPeter Brune   }
1229d5e6173cSPeter Brune   if (Ystage) {
1230d5e6173cSPeter Brune     if (dm && dm != ts->dm) {
1231d5e6173cSPeter Brune       ierr = DMRestoreNamedGlobalVector(dm,"TSRosW_Ystage",Ystage);CHKERRQ(ierr);
1232d5e6173cSPeter Brune     }
1233d5e6173cSPeter Brune   }
1234d5e6173cSPeter Brune   if (Zstage) {
1235d5e6173cSPeter Brune     if (dm && dm != ts->dm) {
1236d5e6173cSPeter Brune       ierr = DMRestoreNamedGlobalVector(dm,"TSRosW_Zstage",Zstage);CHKERRQ(ierr);
1237d5e6173cSPeter Brune     }
1238d5e6173cSPeter Brune   }
1239d5e6173cSPeter Brune   PetscFunctionReturn(0);
1240d5e6173cSPeter Brune }
1241d5e6173cSPeter Brune 
1242d5e6173cSPeter Brune #undef __FUNCT__
1243d5e6173cSPeter Brune #define __FUNCT__ "DMCoarsenHook_TSRosW"
1244d5e6173cSPeter Brune static PetscErrorCode DMCoarsenHook_TSRosW(DM fine,DM coarse,void *ctx)
1245d5e6173cSPeter Brune {
1246d5e6173cSPeter Brune   PetscFunctionBegin;
1247d5e6173cSPeter Brune   PetscFunctionReturn(0);
1248d5e6173cSPeter Brune }
1249d5e6173cSPeter Brune 
1250d5e6173cSPeter Brune #undef __FUNCT__
1251d5e6173cSPeter Brune #define __FUNCT__ "DMRestrictHook_TSRosW"
1252d5e6173cSPeter Brune static PetscErrorCode DMRestrictHook_TSRosW(DM fine,Mat restrct,Vec rscale,Mat inject,DM coarse,void *ctx)
1253d5e6173cSPeter Brune {
1254d5e6173cSPeter Brune   TS             ts = (TS)ctx;
1255d5e6173cSPeter Brune   PetscErrorCode ierr;
1256d5e6173cSPeter Brune   Vec            Ydot,Zdot,Ystage,Zstage;
1257d5e6173cSPeter Brune   Vec            Ydotc,Zdotc,Ystagec,Zstagec;
1258d5e6173cSPeter Brune 
1259d5e6173cSPeter Brune   PetscFunctionBegin;
1260d5e6173cSPeter Brune   ierr = TSRosWGetVecs(ts,fine,&Ydot,&Ystage,&Zdot,&Zstage);CHKERRQ(ierr);
1261d5e6173cSPeter Brune   ierr = TSRosWGetVecs(ts,coarse,&Ydotc,&Ystagec,&Zdotc,&Zstagec);CHKERRQ(ierr);
1262d5e6173cSPeter Brune   ierr = MatRestrict(restrct,Ydot,Ydotc);CHKERRQ(ierr);
1263d5e6173cSPeter Brune   ierr = VecPointwiseMult(Ydotc,rscale,Ydotc);CHKERRQ(ierr);
1264d5e6173cSPeter Brune   ierr = MatRestrict(restrct,Ystage,Ystagec);CHKERRQ(ierr);
1265d5e6173cSPeter Brune   ierr = VecPointwiseMult(Ystagec,rscale,Ystagec);CHKERRQ(ierr);
1266d5e6173cSPeter Brune   ierr = MatRestrict(restrct,Zdot,Zdotc);CHKERRQ(ierr);
1267d5e6173cSPeter Brune   ierr = VecPointwiseMult(Zdotc,rscale,Zdotc);CHKERRQ(ierr);
1268d5e6173cSPeter Brune   ierr = MatRestrict(restrct,Zstage,Zstagec);CHKERRQ(ierr);
1269d5e6173cSPeter Brune   ierr = VecPointwiseMult(Zstagec,rscale,Zstagec);CHKERRQ(ierr);
1270d5e6173cSPeter Brune   ierr = TSRosWRestoreVecs(ts,fine,&Ydot,&Ystage,&Zdot,&Zstage);CHKERRQ(ierr);
1271d5e6173cSPeter Brune   ierr = TSRosWRestoreVecs(ts,coarse,&Ydotc,&Ystagec,&Zdotc,&Zstagec);CHKERRQ(ierr);
1272d5e6173cSPeter Brune   PetscFunctionReturn(0);
1273d5e6173cSPeter Brune }
1274d5e6173cSPeter Brune 
1275258e1594SPeter Brune 
1276258e1594SPeter Brune #undef __FUNCT__
1277258e1594SPeter Brune #define __FUNCT__ "DMSubDomainHook_TSRosW"
1278258e1594SPeter Brune static PetscErrorCode DMSubDomainHook_TSRosW(DM fine,DM coarse,void *ctx)
1279258e1594SPeter Brune {
1280258e1594SPeter Brune   PetscFunctionBegin;
1281258e1594SPeter Brune   PetscFunctionReturn(0);
1282258e1594SPeter Brune }
1283258e1594SPeter Brune 
1284258e1594SPeter Brune #undef __FUNCT__
1285258e1594SPeter Brune #define __FUNCT__ "DMSubDomainRestrictHook_TSRosW"
1286258e1594SPeter Brune static PetscErrorCode DMSubDomainRestrictHook_TSRosW(DM dm,VecScatter gscat,VecScatter lscat,DM subdm,void *ctx)
1287258e1594SPeter Brune {
1288258e1594SPeter Brune   TS             ts = (TS)ctx;
1289258e1594SPeter Brune   PetscErrorCode ierr;
1290258e1594SPeter Brune   Vec            Ydot,Zdot,Ystage,Zstage;
1291258e1594SPeter Brune   Vec            Ydots,Zdots,Ystages,Zstages;
1292258e1594SPeter Brune 
1293258e1594SPeter Brune   PetscFunctionBegin;
1294258e1594SPeter Brune   ierr = TSRosWGetVecs(ts,dm,&Ydot,&Ystage,&Zdot,&Zstage);CHKERRQ(ierr);
1295258e1594SPeter Brune   ierr = TSRosWGetVecs(ts,subdm,&Ydots,&Ystages,&Zdots,&Zstages);CHKERRQ(ierr);
1296258e1594SPeter Brune 
1297258e1594SPeter Brune   ierr = VecScatterBegin(gscat,Ydot,Ydots,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
1298258e1594SPeter Brune   ierr = VecScatterEnd(gscat,Ydot,Ydots,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
1299258e1594SPeter Brune 
1300258e1594SPeter Brune   ierr = VecScatterBegin(gscat,Ystage,Ystages,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
1301258e1594SPeter Brune   ierr = VecScatterEnd(gscat,Ystage,Ystages,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
1302258e1594SPeter Brune 
1303258e1594SPeter Brune   ierr = VecScatterBegin(gscat,Zdot,Zdots,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
1304258e1594SPeter Brune   ierr = VecScatterEnd(gscat,Zdot,Zdots,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
1305258e1594SPeter Brune 
1306258e1594SPeter Brune   ierr = VecScatterBegin(gscat,Zstage,Zstages,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
1307258e1594SPeter Brune   ierr = VecScatterEnd(gscat,Zstage,Zstages,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
1308258e1594SPeter Brune 
1309258e1594SPeter Brune   ierr = TSRosWRestoreVecs(ts,dm,&Ydot,&Ystage,&Zdot,&Zstage);CHKERRQ(ierr);
1310258e1594SPeter Brune   ierr = TSRosWRestoreVecs(ts,subdm,&Ydots,&Ystages,&Zdots,&Zstages);CHKERRQ(ierr);
1311258e1594SPeter Brune   PetscFunctionReturn(0);
1312258e1594SPeter Brune }
1313258e1594SPeter Brune 
1314e27a552bSJed Brown /*
1315e27a552bSJed Brown   This defines the nonlinear equation that is to be solved with SNES
1316e27a552bSJed Brown   G(U) = F[t0+Theta*dt, U, (U-U0)*shift] = 0
1317e27a552bSJed Brown */
1318e27a552bSJed Brown #undef __FUNCT__
1319e27a552bSJed Brown #define __FUNCT__ "SNESTSFormFunction_RosW"
1320f9c1d6abSBarry Smith static PetscErrorCode SNESTSFormFunction_RosW(SNES snes,Vec U,Vec F,TS ts)
1321e27a552bSJed Brown {
132261692a83SJed Brown   TS_RosW        *ros = (TS_RosW*)ts->data;
1323e27a552bSJed Brown   PetscErrorCode ierr;
1324d5e6173cSPeter Brune   Vec            Ydot,Zdot,Ystage,Zstage;
1325b296d7d5SJed Brown   PetscReal      shift = ros->scoeff / ts->time_step;
1326d5e6173cSPeter Brune   DM             dm,dmsave;
1327e27a552bSJed Brown 
1328e27a552bSJed Brown   PetscFunctionBegin;
1329d5e6173cSPeter Brune   ierr   = SNESGetDM(snes,&dm);CHKERRQ(ierr);
1330d5e6173cSPeter Brune   ierr   = TSRosWGetVecs(ts,dm,&Ydot,&Zdot,&Ystage,&Zstage);CHKERRQ(ierr);
1331b296d7d5SJed Brown   ierr   = VecWAXPY(Ydot,shift,U,Zdot);CHKERRQ(ierr);    /* Ydot = shift*U + Zdot */
1332f9c1d6abSBarry Smith   ierr   = VecWAXPY(Ystage,1.0,U,Zstage);CHKERRQ(ierr);  /* Ystage = U + Zstage */
1333d5e6173cSPeter Brune   dmsave = ts->dm;
1334d5e6173cSPeter Brune   ts->dm = dm;
1335d5e6173cSPeter Brune   ierr   = TSComputeIFunction(ts,ros->stage_time,Ystage,Ydot,F,PETSC_FALSE);CHKERRQ(ierr);
1336d5e6173cSPeter Brune   ts->dm = dmsave;
1337d5e6173cSPeter Brune   ierr   = TSRosWRestoreVecs(ts,dm,&Ydot,&Zdot,&Ystage,&Zstage);CHKERRQ(ierr);
1338e27a552bSJed Brown   PetscFunctionReturn(0);
1339e27a552bSJed Brown }
1340e27a552bSJed Brown 
1341e27a552bSJed Brown #undef __FUNCT__
1342e27a552bSJed Brown #define __FUNCT__ "SNESTSFormJacobian_RosW"
1343f9c1d6abSBarry Smith static PetscErrorCode SNESTSFormJacobian_RosW(SNES snes,Vec U,Mat *A,Mat *B,MatStructure *str,TS ts)
1344e27a552bSJed Brown {
134561692a83SJed Brown   TS_RosW        *ros = (TS_RosW*)ts->data;
1346d5e6173cSPeter Brune   Vec            Ydot,Zdot,Ystage,Zstage;
1347b296d7d5SJed Brown   PetscReal      shift = ros->scoeff / ts->time_step;
1348e27a552bSJed Brown   PetscErrorCode ierr;
1349d5e6173cSPeter Brune   DM             dm,dmsave;
1350e27a552bSJed Brown 
1351e27a552bSJed Brown   PetscFunctionBegin;
135261692a83SJed Brown   /* ros->Ydot and ros->Ystage have already been computed in SNESTSFormFunction_RosW (SNES guarantees this) */
1353d5e6173cSPeter Brune   ierr   = SNESGetDM(snes,&dm);CHKERRQ(ierr);
1354d5e6173cSPeter Brune   ierr   = TSRosWGetVecs(ts,dm,&Ydot,&Zdot,&Ystage,&Zstage);CHKERRQ(ierr);
1355d5e6173cSPeter Brune   dmsave = ts->dm;
1356d5e6173cSPeter Brune   ts->dm = dm;
1357b296d7d5SJed Brown   ierr   = TSComputeIJacobian(ts,ros->stage_time,Ystage,Ydot,shift,A,B,str,PETSC_TRUE);CHKERRQ(ierr);
1358d5e6173cSPeter Brune   ts->dm = dmsave;
1359d5e6173cSPeter Brune   ierr   = TSRosWRestoreVecs(ts,dm,&Ydot,&Zdot,&Ystage,&Zstage);CHKERRQ(ierr);
1360e27a552bSJed Brown   PetscFunctionReturn(0);
1361e27a552bSJed Brown }
1362e27a552bSJed Brown 
1363e27a552bSJed Brown #undef __FUNCT__
1364e27a552bSJed Brown #define __FUNCT__ "TSSetUp_RosW"
1365e27a552bSJed Brown static PetscErrorCode TSSetUp_RosW(TS ts)
1366e27a552bSJed Brown {
136761692a83SJed Brown   TS_RosW        *ros = (TS_RosW*)ts->data;
136861692a83SJed Brown   RosWTableau    tab  = ros->tableau;
1369e27a552bSJed Brown   PetscInt       s    = tab->s;
1370e27a552bSJed Brown   PetscErrorCode ierr;
1371d5e6173cSPeter Brune   DM             dm;
1372e27a552bSJed Brown 
1373e27a552bSJed Brown   PetscFunctionBegin;
137461692a83SJed Brown   if (!ros->tableau) {
1375e27a552bSJed Brown     ierr = TSRosWSetType(ts,TSRosWDefault);CHKERRQ(ierr);
1376e27a552bSJed Brown   }
137761692a83SJed Brown   ierr = VecDuplicateVecs(ts->vec_sol,s,&ros->Y);CHKERRQ(ierr);
137861692a83SJed Brown   ierr = VecDuplicate(ts->vec_sol,&ros->Ydot);CHKERRQ(ierr);
137961692a83SJed Brown   ierr = VecDuplicate(ts->vec_sol,&ros->Ystage);CHKERRQ(ierr);
138061692a83SJed Brown   ierr = VecDuplicate(ts->vec_sol,&ros->Zdot);CHKERRQ(ierr);
138161692a83SJed Brown   ierr = VecDuplicate(ts->vec_sol,&ros->Zstage);CHKERRQ(ierr);
13823ca35412SEmil Constantinescu   ierr = VecDuplicate(ts->vec_sol,&ros->VecSolPrev);CHKERRQ(ierr);
138361692a83SJed Brown   ierr = PetscMalloc(s*sizeof(ros->work[0]),&ros->work);CHKERRQ(ierr);
138422d28d08SBarry Smith   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
1385d5e6173cSPeter Brune   if (dm) {
1386d5e6173cSPeter Brune     ierr = DMCoarsenHookAdd(dm,DMCoarsenHook_TSRosW,DMRestrictHook_TSRosW,ts);CHKERRQ(ierr);
1387258e1594SPeter Brune     ierr = DMSubDomainHookAdd(dm,DMSubDomainHook_TSRosW,DMSubDomainRestrictHook_TSRosW,ts);CHKERRQ(ierr);
1388d5e6173cSPeter Brune   }
1389e27a552bSJed Brown   PetscFunctionReturn(0);
1390e27a552bSJed Brown }
1391e27a552bSJed Brown /*------------------------------------------------------------*/
1392e27a552bSJed Brown 
1393e27a552bSJed Brown #undef __FUNCT__
1394e27a552bSJed Brown #define __FUNCT__ "TSSetFromOptions_RosW"
1395e27a552bSJed Brown static PetscErrorCode TSSetFromOptions_RosW(TS ts)
1396e27a552bSJed Brown {
139761692a83SJed Brown   TS_RosW        *ros = (TS_RosW*)ts->data;
1398e27a552bSJed Brown   PetscErrorCode ierr;
139961692a83SJed Brown   char           rostype[256];
1400e27a552bSJed Brown 
1401e27a552bSJed Brown   PetscFunctionBegin;
1402e27a552bSJed Brown   ierr = PetscOptionsHead("RosW ODE solver options");CHKERRQ(ierr);
1403e27a552bSJed Brown   {
140461692a83SJed Brown     RosWTableauLink link;
1405e27a552bSJed Brown     PetscInt        count,choice;
1406e27a552bSJed Brown     PetscBool       flg;
1407e27a552bSJed Brown     const char      **namelist;
140861692a83SJed Brown     SNES            snes;
140961692a83SJed Brown 
14108caf3d72SBarry Smith     ierr = PetscStrncpy(rostype,TSRosWDefault,sizeof(rostype));CHKERRQ(ierr);
141161692a83SJed Brown     for (link=RosWTableauList,count=0; link; link=link->next,count++) ;
1412e27a552bSJed Brown     ierr = PetscMalloc(count*sizeof(char*),&namelist);CHKERRQ(ierr);
141361692a83SJed Brown     for (link=RosWTableauList,count=0; link; link=link->next,count++) namelist[count] = link->tab.name;
141461692a83SJed Brown     ierr = PetscOptionsEList("-ts_rosw_type","Family of Rosenbrock-W method","TSRosWSetType",(const char*const*)namelist,count,rostype,&choice,&flg);CHKERRQ(ierr);
141561692a83SJed Brown     ierr = TSRosWSetType(ts,flg ? namelist[choice] : rostype);CHKERRQ(ierr);
1416e27a552bSJed Brown     ierr = PetscFree(namelist);CHKERRQ(ierr);
141761692a83SJed Brown 
14180298fd71SBarry Smith     ierr = PetscOptionsBool("-ts_rosw_recompute_jacobian","Recompute the Jacobian at each stage","TSRosWSetRecomputeJacobian",ros->recompute_jacobian,&ros->recompute_jacobian,NULL);CHKERRQ(ierr);
141961692a83SJed Brown 
142061692a83SJed Brown     /* Rosenbrock methods are linearly implicit, so set that unless the user has specifically asked for something else */
142161692a83SJed Brown     ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
142261692a83SJed Brown     if (!((PetscObject)snes)->type_name) {
142361692a83SJed Brown       ierr = SNESSetType(snes,SNESKSPONLY);CHKERRQ(ierr);
142461692a83SJed Brown     }
142561692a83SJed Brown     ierr = SNESSetFromOptions(snes);CHKERRQ(ierr);
1426e27a552bSJed Brown   }
1427e27a552bSJed Brown   ierr = PetscOptionsTail();CHKERRQ(ierr);
1428e27a552bSJed Brown   PetscFunctionReturn(0);
1429e27a552bSJed Brown }
1430e27a552bSJed Brown 
1431e27a552bSJed Brown #undef __FUNCT__
1432e27a552bSJed Brown #define __FUNCT__ "PetscFormatRealArray"
1433e27a552bSJed Brown static PetscErrorCode PetscFormatRealArray(char buf[],size_t len,const char *fmt,PetscInt n,const PetscReal x[])
1434e27a552bSJed Brown {
1435e27a552bSJed Brown   PetscErrorCode ierr;
1436e408995aSJed Brown   PetscInt       i;
1437e408995aSJed Brown   size_t         left,count;
1438e27a552bSJed Brown   char           *p;
1439e27a552bSJed Brown 
1440e27a552bSJed Brown   PetscFunctionBegin;
1441e408995aSJed Brown   for (i=0,p=buf,left=len; i<n; i++) {
1442e408995aSJed Brown     ierr = PetscSNPrintfCount(p,left,fmt,&count,x[i]);CHKERRQ(ierr);
1443e27a552bSJed Brown     if (count >= left) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Insufficient space in buffer");
1444e27a552bSJed Brown     left -= count;
1445e27a552bSJed Brown     p    += count;
1446e27a552bSJed Brown     *p++  = ' ';
1447e27a552bSJed Brown   }
1448e27a552bSJed Brown   p[i ? 0 : -1] = 0;
1449e27a552bSJed Brown   PetscFunctionReturn(0);
1450e27a552bSJed Brown }
1451e27a552bSJed Brown 
1452e27a552bSJed Brown #undef __FUNCT__
1453e27a552bSJed Brown #define __FUNCT__ "TSView_RosW"
1454e27a552bSJed Brown static PetscErrorCode TSView_RosW(TS ts,PetscViewer viewer)
1455e27a552bSJed Brown {
145661692a83SJed Brown   TS_RosW        *ros = (TS_RosW*)ts->data;
145761692a83SJed Brown   RosWTableau    tab  = ros->tableau;
1458e27a552bSJed Brown   PetscBool      iascii;
1459e27a552bSJed Brown   PetscErrorCode ierr;
1460ef20d060SBarry Smith   TSAdapt        adapt;
1461e27a552bSJed Brown 
1462e27a552bSJed Brown   PetscFunctionBegin;
1463251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1464e27a552bSJed Brown   if (iascii) {
146519fd82e9SBarry Smith     TSRosWType rostype;
1466e408995aSJed Brown     PetscInt   i;
1467e408995aSJed Brown     PetscReal  abscissa[512];
1468e27a552bSJed Brown     char       buf[512];
146961692a83SJed Brown     ierr = TSRosWGetType(ts,&rostype);CHKERRQ(ierr);
147061692a83SJed Brown     ierr = PetscViewerASCIIPrintf(viewer,"  Rosenbrock-W %s\n",rostype);CHKERRQ(ierr);
14718caf3d72SBarry Smith     ierr = PetscFormatRealArray(buf,sizeof(buf),"% 8.6f",tab->s,tab->ASum);CHKERRQ(ierr);
147261692a83SJed Brown     ierr = PetscViewerASCIIPrintf(viewer,"  Abscissa of A       = %s\n",buf);CHKERRQ(ierr);
1473e408995aSJed Brown     for (i=0; i<tab->s; i++) abscissa[i] = tab->ASum[i] + tab->Gamma[i];
14748caf3d72SBarry Smith     ierr = PetscFormatRealArray(buf,sizeof(buf),"% 8.6f",tab->s,abscissa);CHKERRQ(ierr);
1475e408995aSJed Brown     ierr = PetscViewerASCIIPrintf(viewer,"  Abscissa of A+Gamma = %s\n",buf);CHKERRQ(ierr);
1476e27a552bSJed Brown   }
1477ad6bc421SBarry Smith   ierr = TSGetTSAdapt(ts,&adapt);CHKERRQ(ierr);
1478ef20d060SBarry Smith   ierr = TSAdaptView(adapt,viewer);CHKERRQ(ierr);
1479e27a552bSJed Brown   ierr = SNESView(ts->snes,viewer);CHKERRQ(ierr);
1480e27a552bSJed Brown   PetscFunctionReturn(0);
1481e27a552bSJed Brown }
1482e27a552bSJed Brown 
1483e27a552bSJed Brown #undef __FUNCT__
1484e27a552bSJed Brown #define __FUNCT__ "TSRosWSetType"
1485e27a552bSJed Brown /*@C
148661692a83SJed Brown   TSRosWSetType - Set the type of Rosenbrock-W scheme
1487e27a552bSJed Brown 
1488e27a552bSJed Brown   Logically collective
1489e27a552bSJed Brown 
1490e27a552bSJed Brown   Input Parameter:
1491e27a552bSJed Brown +  ts - timestepping context
149261692a83SJed Brown -  rostype - type of Rosenbrock-W scheme
1493e27a552bSJed Brown 
1494020d8f30SJed Brown   Level: beginner
1495e27a552bSJed Brown 
1496020d8f30SJed Brown .seealso: TSRosWGetType(), TSROSW, TSROSW2M, TSROSW2P, TSROSWRA3PW, TSROSWRA34PW2, TSROSWRODAS3, TSROSWSANDU3, TSROSWASSP3P3S1C, TSROSWLASSP3P4S2C, TSROSWLLSSP3P4S2C, TSROSWARK3
1497e27a552bSJed Brown @*/
149819fd82e9SBarry Smith PetscErrorCode TSRosWSetType(TS ts,TSRosWType rostype)
1499e27a552bSJed Brown {
1500e27a552bSJed Brown   PetscErrorCode ierr;
1501e27a552bSJed Brown 
1502e27a552bSJed Brown   PetscFunctionBegin;
1503e27a552bSJed Brown   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
150419fd82e9SBarry Smith   ierr = PetscTryMethod(ts,"TSRosWSetType_C",(TS,TSRosWType),(ts,rostype));CHKERRQ(ierr);
1505e27a552bSJed Brown   PetscFunctionReturn(0);
1506e27a552bSJed Brown }
1507e27a552bSJed Brown 
1508e27a552bSJed Brown #undef __FUNCT__
1509e27a552bSJed Brown #define __FUNCT__ "TSRosWGetType"
1510e27a552bSJed Brown /*@C
151161692a83SJed Brown   TSRosWGetType - Get the type of Rosenbrock-W scheme
1512e27a552bSJed Brown 
1513e27a552bSJed Brown   Logically collective
1514e27a552bSJed Brown 
1515e27a552bSJed Brown   Input Parameter:
1516e27a552bSJed Brown .  ts - timestepping context
1517e27a552bSJed Brown 
1518e27a552bSJed Brown   Output Parameter:
151961692a83SJed Brown .  rostype - type of Rosenbrock-W scheme
1520e27a552bSJed Brown 
1521e27a552bSJed Brown   Level: intermediate
1522e27a552bSJed Brown 
1523e27a552bSJed Brown .seealso: TSRosWGetType()
1524e27a552bSJed Brown @*/
152519fd82e9SBarry Smith PetscErrorCode TSRosWGetType(TS ts,TSRosWType *rostype)
1526e27a552bSJed Brown {
1527e27a552bSJed Brown   PetscErrorCode ierr;
1528e27a552bSJed Brown 
1529e27a552bSJed Brown   PetscFunctionBegin;
1530e27a552bSJed Brown   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
153119fd82e9SBarry Smith   ierr = PetscUseMethod(ts,"TSRosWGetType_C",(TS,TSRosWType*),(ts,rostype));CHKERRQ(ierr);
1532e27a552bSJed Brown   PetscFunctionReturn(0);
1533e27a552bSJed Brown }
1534e27a552bSJed Brown 
1535e27a552bSJed Brown #undef __FUNCT__
153661692a83SJed Brown #define __FUNCT__ "TSRosWSetRecomputeJacobian"
1537e27a552bSJed Brown /*@C
153861692a83SJed Brown   TSRosWSetRecomputeJacobian - Set whether to recompute the Jacobian at each stage. The default is to update the Jacobian once per step.
1539e27a552bSJed Brown 
1540e27a552bSJed Brown   Logically collective
1541e27a552bSJed Brown 
1542e27a552bSJed Brown   Input Parameter:
1543e27a552bSJed Brown +  ts - timestepping context
154461692a83SJed Brown -  flg - PETSC_TRUE to recompute the Jacobian at each stage
1545e27a552bSJed Brown 
1546e27a552bSJed Brown   Level: intermediate
1547e27a552bSJed Brown 
1548e27a552bSJed Brown .seealso: TSRosWGetType()
1549e27a552bSJed Brown @*/
155061692a83SJed Brown PetscErrorCode TSRosWSetRecomputeJacobian(TS ts,PetscBool flg)
1551e27a552bSJed Brown {
1552e27a552bSJed Brown   PetscErrorCode ierr;
1553e27a552bSJed Brown 
1554e27a552bSJed Brown   PetscFunctionBegin;
1555e27a552bSJed Brown   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
155661692a83SJed Brown   ierr = PetscTryMethod(ts,"TSRosWSetRecomputeJacobian_C",(TS,PetscBool),(ts,flg));CHKERRQ(ierr);
1557e27a552bSJed Brown   PetscFunctionReturn(0);
1558e27a552bSJed Brown }
1559e27a552bSJed Brown 
1560e27a552bSJed Brown EXTERN_C_BEGIN
1561e27a552bSJed Brown #undef __FUNCT__
1562e27a552bSJed Brown #define __FUNCT__ "TSRosWGetType_RosW"
156319fd82e9SBarry Smith PetscErrorCode  TSRosWGetType_RosW(TS ts,TSRosWType *rostype)
1564e27a552bSJed Brown {
156561692a83SJed Brown   TS_RosW        *ros = (TS_RosW*)ts->data;
1566e27a552bSJed Brown   PetscErrorCode ierr;
1567e27a552bSJed Brown 
1568e27a552bSJed Brown   PetscFunctionBegin;
156961692a83SJed Brown   if (!ros->tableau) {ierr = TSRosWSetType(ts,TSRosWDefault);CHKERRQ(ierr);}
157061692a83SJed Brown   *rostype = ros->tableau->name;
1571e27a552bSJed Brown   PetscFunctionReturn(0);
1572e27a552bSJed Brown }
1573ef20d060SBarry Smith 
1574e27a552bSJed Brown #undef __FUNCT__
1575e27a552bSJed Brown #define __FUNCT__ "TSRosWSetType_RosW"
157619fd82e9SBarry Smith PetscErrorCode  TSRosWSetType_RosW(TS ts,TSRosWType rostype)
1577e27a552bSJed Brown {
157861692a83SJed Brown   TS_RosW         *ros = (TS_RosW*)ts->data;
1579e27a552bSJed Brown   PetscErrorCode  ierr;
1580e27a552bSJed Brown   PetscBool       match;
158161692a83SJed Brown   RosWTableauLink link;
1582e27a552bSJed Brown 
1583e27a552bSJed Brown   PetscFunctionBegin;
158461692a83SJed Brown   if (ros->tableau) {
158561692a83SJed Brown     ierr = PetscStrcmp(ros->tableau->name,rostype,&match);CHKERRQ(ierr);
1586e27a552bSJed Brown     if (match) PetscFunctionReturn(0);
1587e27a552bSJed Brown   }
158861692a83SJed Brown   for (link = RosWTableauList; link; link=link->next) {
158961692a83SJed Brown     ierr = PetscStrcmp(link->tab.name,rostype,&match);CHKERRQ(ierr);
1590e27a552bSJed Brown     if (match) {
1591e27a552bSJed Brown       ierr = TSReset_RosW(ts);CHKERRQ(ierr);
159261692a83SJed Brown       ros->tableau = &link->tab;
1593e27a552bSJed Brown       PetscFunctionReturn(0);
1594e27a552bSJed Brown     }
1595e27a552bSJed Brown   }
1596*ce94432eSBarry Smith   SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_UNKNOWN_TYPE,"Could not find '%s'",rostype);
1597e27a552bSJed Brown   PetscFunctionReturn(0);
1598e27a552bSJed Brown }
159961692a83SJed Brown 
1600e27a552bSJed Brown #undef __FUNCT__
160161692a83SJed Brown #define __FUNCT__ "TSRosWSetRecomputeJacobian_RosW"
160261692a83SJed Brown PetscErrorCode  TSRosWSetRecomputeJacobian_RosW(TS ts,PetscBool flg)
1603e27a552bSJed Brown {
160461692a83SJed Brown   TS_RosW *ros = (TS_RosW*)ts->data;
1605e27a552bSJed Brown 
1606e27a552bSJed Brown   PetscFunctionBegin;
160761692a83SJed Brown   ros->recompute_jacobian = flg;
1608e27a552bSJed Brown   PetscFunctionReturn(0);
1609e27a552bSJed Brown }
1610e27a552bSJed Brown EXTERN_C_END
1611e27a552bSJed Brown 
1612d5e6173cSPeter Brune 
1613e27a552bSJed Brown /* ------------------------------------------------------------ */
1614e27a552bSJed Brown /*MC
1615020d8f30SJed Brown       TSROSW - ODE solver using Rosenbrock-W schemes
1616e27a552bSJed Brown 
1617e27a552bSJed Brown   These methods are intended for problems with well-separated time scales, especially when a slow scale is strongly
1618e27a552bSJed Brown   nonlinear such that it is expensive to solve with a fully implicit method. The user should provide the stiff part
1619e27a552bSJed Brown   of the equation using TSSetIFunction() and the non-stiff part with TSSetRHSFunction().
1620e27a552bSJed Brown 
1621e27a552bSJed Brown   Notes:
162261692a83SJed Brown   This method currently only works with autonomous ODE and DAE.
162361692a83SJed Brown 
162461692a83SJed Brown   Developer notes:
162561692a83SJed Brown   Rosenbrock-W methods are typically specified for autonomous ODE
162661692a83SJed Brown 
1627f9c1d6abSBarry Smith $  udot = f(u)
162861692a83SJed Brown 
162961692a83SJed Brown   by the stage equations
163061692a83SJed Brown 
1631f9c1d6abSBarry Smith $  k_i = h f(u_0 + sum_j alpha_ij k_j) + h J sum_j gamma_ij k_j
163261692a83SJed Brown 
163361692a83SJed Brown   and step completion formula
163461692a83SJed Brown 
1635f9c1d6abSBarry Smith $  u_1 = u_0 + sum_j b_j k_j
163661692a83SJed Brown 
1637f9c1d6abSBarry Smith   with step size h and coefficients alpha_ij, gamma_ij, and b_i. Implementing the method in this form would require f(u)
163861692a83SJed Brown   and the Jacobian J to be available, in addition to the shifted matrix I - h gamma_ii J. Following Hairer and Wanner,
163961692a83SJed Brown   we define new variables for the stage equations
164061692a83SJed Brown 
164161692a83SJed Brown $  y_i = gamma_ij k_j
164261692a83SJed Brown 
164361692a83SJed Brown   The k_j can be recovered because Gamma is invertible. Let C be the lower triangular part of Gamma^{-1} and define
164461692a83SJed Brown 
164561692a83SJed Brown $  A = Alpha Gamma^{-1}, bt^T = b^T Gamma^{-i}
164661692a83SJed Brown 
164761692a83SJed Brown   to rewrite the method as
164861692a83SJed Brown 
1649f9c1d6abSBarry 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
1650f9c1d6abSBarry Smith $  u_1 = u_0 + sum_j bt_j y_j
165161692a83SJed Brown 
165261692a83SJed Brown    where we have introduced the mass matrix M. Continue by defining
165361692a83SJed Brown 
165461692a83SJed Brown $  ydot_i = 1/(h gamma_ii) y_i - sum_j (c_ij/h) y_j
165561692a83SJed Brown 
165661692a83SJed Brown    or, more compactly in tensor notation
165761692a83SJed Brown 
165861692a83SJed Brown $  Ydot = 1/h (Gamma^{-1} \otimes I) Y .
165961692a83SJed Brown 
166061692a83SJed Brown    Note that Gamma^{-1} is lower triangular. With this definition of Ydot in terms of known quantities and the current
166161692a83SJed Brown    stage y_i, the stage equations reduce to performing one Newton step (typically with a lagged Jacobian) on the
166261692a83SJed Brown    equation
166361692a83SJed Brown 
1664f9c1d6abSBarry Smith $  g(u_0 + sum_j a_ij y_j + y_i, ydot_i) = 0
166561692a83SJed Brown 
166661692a83SJed Brown    with initial guess y_i = 0.
1667e27a552bSJed Brown 
1668e27a552bSJed Brown   Level: beginner
1669e27a552bSJed Brown 
1670a4386c9eSJed Brown .seealso:  TSCreate(), TS, TSSetType(), TSRosWSetType(), TSRosWRegister(), TSROSW2M, TSROSW2P, TSROSWRA3PW, TSROSWRA34PW2, TSROSWRODAS3,
1671a4386c9eSJed Brown            TSROSWSANDU3, TSROSWASSP3P3S1C, TSROSWLASSP3P4S2C, TSROSWLLSSP3P4S2C, TSROSWGRK4T, TSROSWSHAMP4, TSROSWVELDD4, TSROSW4L
1672e27a552bSJed Brown M*/
1673e27a552bSJed Brown EXTERN_C_BEGIN
1674e27a552bSJed Brown #undef __FUNCT__
1675e27a552bSJed Brown #define __FUNCT__ "TSCreate_RosW"
1676e27a552bSJed Brown PetscErrorCode  TSCreate_RosW(TS ts)
1677e27a552bSJed Brown {
167861692a83SJed Brown   TS_RosW        *ros;
1679e27a552bSJed Brown   PetscErrorCode ierr;
1680e27a552bSJed Brown 
1681e27a552bSJed Brown   PetscFunctionBegin;
1682e27a552bSJed Brown #if !defined(PETSC_USE_DYNAMIC_LIBRARIES)
16830298fd71SBarry Smith   ierr = TSRosWInitializePackage(NULL);CHKERRQ(ierr);
1684e27a552bSJed Brown #endif
1685e27a552bSJed Brown 
1686e27a552bSJed Brown   ts->ops->reset          = TSReset_RosW;
1687e27a552bSJed Brown   ts->ops->destroy        = TSDestroy_RosW;
1688e27a552bSJed Brown   ts->ops->view           = TSView_RosW;
1689e27a552bSJed Brown   ts->ops->setup          = TSSetUp_RosW;
1690e27a552bSJed Brown   ts->ops->step           = TSStep_RosW;
1691e27a552bSJed Brown   ts->ops->interpolate    = TSInterpolate_RosW;
16921c3436cfSJed Brown   ts->ops->evaluatestep   = TSEvaluateStep_RosW;
1693e27a552bSJed Brown   ts->ops->setfromoptions = TSSetFromOptions_RosW;
1694e27a552bSJed Brown   ts->ops->snesfunction   = SNESTSFormFunction_RosW;
1695e27a552bSJed Brown   ts->ops->snesjacobian   = SNESTSFormJacobian_RosW;
1696e27a552bSJed Brown 
169761692a83SJed Brown   ierr = PetscNewLog(ts,TS_RosW,&ros);CHKERRQ(ierr);
169861692a83SJed Brown   ts->data = (void*)ros;
1699e27a552bSJed Brown 
1700e27a552bSJed Brown   ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSRosWGetType_C","TSRosWGetType_RosW",TSRosWGetType_RosW);CHKERRQ(ierr);
1701e27a552bSJed Brown   ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSRosWSetType_C","TSRosWSetType_RosW",TSRosWSetType_RosW);CHKERRQ(ierr);
170261692a83SJed Brown   ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSRosWSetRecomputeJacobian_C","TSRosWSetRecomputeJacobian_RosW",TSRosWSetRecomputeJacobian_RosW);CHKERRQ(ierr);
1703e27a552bSJed Brown   PetscFunctionReturn(0);
1704e27a552bSJed Brown }
1705e27a552bSJed Brown EXTERN_C_END
1706