xref: /petsc/src/ts/impls/rosw/rosw.c (revision 1f80e2751dc8c0c04b1d338a6c147781270546f0)
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 
761692a83SJed Brown   G(t,X,Xdot) = F(t,X)
8e27a552bSJed Brown 
961692a83SJed Brown   where G represents the stiff part of the physics and F represents the non-stiff part.
1061692a83SJed Brown   This method is designed to be linearly implicit on G and can use an approximate and lagged Jacobian.
11e27a552bSJed Brown 
12e27a552bSJed Brown */
13e27a552bSJed Brown #include <private/tsimpl.h>                /*I   "petscts.h"   I*/
14e27a552bSJed Brown 
1561692a83SJed Brown #include <../src/mat/blockinvert.h>
1661692a83SJed Brown 
17ae6f9490SJed Brown static const 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() */
58e27a552bSJed Brown   PetscReal   shift;
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
184961f28d0SJed Brown      TSROSWLASSP3P4S2C - L-stable Rosenbrock-W method with SSP explicit part, third order, three 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
19943b21953SEmil Constantinescu      TSROSWLLSSP3P4S2C - L-stable Rosenbrock-W method with SSP explicit part, third order, three 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 
213e27a552bSJed Brown #undef __FUNCT__
214e27a552bSJed Brown #define __FUNCT__ "TSRosWRegisterAll"
215e27a552bSJed Brown /*@C
216e27a552bSJed Brown   TSRosWRegisterAll - Registers all of the additive Runge-Kutta implicit-explicit methods in TSRosW
217e27a552bSJed Brown 
218e27a552bSJed Brown   Not Collective, but should be called by all processes which will need the schemes to be registered
219e27a552bSJed Brown 
220e27a552bSJed Brown   Level: advanced
221e27a552bSJed Brown 
222e27a552bSJed Brown .keywords: TS, TSRosW, register, all
223e27a552bSJed Brown 
224e27a552bSJed Brown .seealso:  TSRosWRegisterDestroy()
225e27a552bSJed Brown @*/
226e27a552bSJed Brown PetscErrorCode TSRosWRegisterAll(void)
227e27a552bSJed Brown {
228e27a552bSJed Brown   PetscErrorCode ierr;
229e27a552bSJed Brown 
230e27a552bSJed Brown   PetscFunctionBegin;
231e27a552bSJed Brown   if (TSRosWRegisterAllCalled) PetscFunctionReturn(0);
232e27a552bSJed Brown   TSRosWRegisterAllCalled = PETSC_TRUE;
233e27a552bSJed Brown 
234e27a552bSJed Brown   {
2353606a31eSEmil Constantinescu     const PetscReal
2363606a31eSEmil Constantinescu       A = 0,
2373606a31eSEmil Constantinescu       Gamma = 1,
238*1f80e275SEmil Constantinescu       b = 1,
239*1f80e275SEmil Constantinescu       binterpt=1;
240*1f80e275SEmil Constantinescu 
241*1f80e275SEmil Constantinescu     ierr = TSRosWRegister(TSROSWTHETA1,1,1,&A,&Gamma,&b,PETSC_NULL,1,&binterpt);CHKERRQ(ierr);
2423606a31eSEmil Constantinescu   }
2433606a31eSEmil Constantinescu 
2443606a31eSEmil Constantinescu   {
2453606a31eSEmil Constantinescu     const PetscReal
2463606a31eSEmil Constantinescu       A= 0,
2473606a31eSEmil Constantinescu       Gamma = 0.5,
248*1f80e275SEmil Constantinescu       b = 1,
249*1f80e275SEmil Constantinescu       binterpt=1;
250*1f80e275SEmil Constantinescu     ierr = TSRosWRegister(TSROSWTHETA2,2,1,&A,&Gamma,&b,PETSC_NULL,1,&binterpt);CHKERRQ(ierr);
2513606a31eSEmil Constantinescu   }
2523606a31eSEmil Constantinescu 
2533606a31eSEmil Constantinescu   {
25461692a83SJed Brown     const PetscReal g = 1. + 1./PetscSqrtReal(2.0);
255e27a552bSJed Brown     const PetscReal
25661692a83SJed Brown       A[2][2] = {{0,0}, {1.,0}},
25761692a83SJed Brown       Gamma[2][2] = {{g,0}, {-2.*g,g}},
2581c3436cfSJed Brown       b[2] = {0.5,0.5},
2591c3436cfSJed Brown       b1[2] = {1.0,0.0};
260*1f80e275SEmil Constantinescu       PetscReal  binterpt[2][2];
261*1f80e275SEmil Constantinescu       binterpt[0][0]=g-1.0;
262*1f80e275SEmil Constantinescu       binterpt[1][0]=2.0-g;
263*1f80e275SEmil Constantinescu       binterpt[0][1]=g-1.5;
264*1f80e275SEmil Constantinescu       binterpt[1][1]=1.5-g;
265*1f80e275SEmil Constantinescu       ierr = TSRosWRegister(TSROSW2P,2,2,&A[0][0],&Gamma[0][0],b,b1,2,&binterpt[0][0]);CHKERRQ(ierr);
266e27a552bSJed Brown   }
267e27a552bSJed Brown   {
26861692a83SJed Brown     const PetscReal g = 1. - 1./PetscSqrtReal(2.0);
269e27a552bSJed Brown     const PetscReal
27061692a83SJed Brown       A[2][2] = {{0,0}, {1.,0}},
27161692a83SJed Brown       Gamma[2][2] = {{g,0}, {-2.*g,g}},
2721c3436cfSJed Brown       b[2] = {0.5,0.5},
2731c3436cfSJed Brown       b1[2] = {1.0,0.0};
274*1f80e275SEmil Constantinescu       PetscReal  binterpt[2][2];
275*1f80e275SEmil Constantinescu       binterpt[0][0]=g-1.0;
276*1f80e275SEmil Constantinescu       binterpt[1][0]=2.0-g;
277*1f80e275SEmil Constantinescu       binterpt[0][1]=g-1.5;
278*1f80e275SEmil Constantinescu       binterpt[1][1]=1.5-g;
279*1f80e275SEmil Constantinescu     ierr = TSRosWRegister(TSROSW2M,2,2,&A[0][0],&Gamma[0][0],b,b1,2,&binterpt[0][0]);CHKERRQ(ierr);
280fe7e6d57SJed Brown   }
281fe7e6d57SJed Brown   {
282fe7e6d57SJed Brown     const PetscReal g = 7.8867513459481287e-01;
283*1f80e275SEmil Constantinescu     PetscReal  binterpt[3][2];
284fe7e6d57SJed Brown     const PetscReal
285fe7e6d57SJed Brown       A[3][3] = {{0,0,0},
286fe7e6d57SJed Brown                  {1.5773502691896257e+00,0,0},
287fe7e6d57SJed Brown                  {0.5,0,0}},
288fe7e6d57SJed Brown       Gamma[3][3] = {{g,0,0},
289fe7e6d57SJed Brown                      {-1.5773502691896257e+00,g,0},
29025833a80SEmil Constantinescu                      {-6.7075317547305480e-01,-1.7075317547305482e-01,g}},
291fe7e6d57SJed Brown       b[3] = {1.0566243270259355e-01,4.9038105676657971e-02,8.4529946162074843e-01},
292fe7e6d57SJed Brown       b2[3] = {-1.7863279495408180e-01,1./3.,8.4529946162074843e-01};
293*1f80e275SEmil Constantinescu 
294*1f80e275SEmil Constantinescu       binterpt[0][0]=-0.8094010767585034;
295*1f80e275SEmil Constantinescu       binterpt[1][0]=-0.5;
296*1f80e275SEmil Constantinescu       binterpt[2][0]=2.3094010767585034;
297*1f80e275SEmil Constantinescu       binterpt[0][1]=0.9641016151377548;
298*1f80e275SEmil Constantinescu       binterpt[1][1]=0.5;
299*1f80e275SEmil Constantinescu       binterpt[2][1]=-1.4641016151377548;
300*1f80e275SEmil Constantinescu       ierr = TSRosWRegister(TSROSWRA3PW,3,3,&A[0][0],&Gamma[0][0],b,b2,2,&binterpt[0][0]);CHKERRQ(ierr);
301fe7e6d57SJed Brown   }
302fe7e6d57SJed Brown   {
3033ca35412SEmil Constantinescu     PetscReal  binterpt[4][3];
304fe7e6d57SJed Brown     const PetscReal g = 4.3586652150845900e-01;
305fe7e6d57SJed Brown     const PetscReal
306fe7e6d57SJed Brown       A[4][4] = {{0,0,0,0},
307fe7e6d57SJed Brown                  {8.7173304301691801e-01,0,0,0},
308fe7e6d57SJed Brown                  {8.4457060015369423e-01,-1.1299064236484185e-01,0,0},
309fe7e6d57SJed Brown                  {0,0,1.,0}},
310fe7e6d57SJed Brown       Gamma[4][4] = {{g,0,0,0},
311fe7e6d57SJed Brown                      {-8.7173304301691801e-01,g,0,0},
312fe7e6d57SJed Brown                      {-9.0338057013044082e-01,5.4180672388095326e-02,g,0},
313fe7e6d57SJed Brown                      {2.4212380706095346e-01,-1.2232505839045147e+00,5.4526025533510214e-01,g}},
314fe7e6d57SJed Brown         b[4] = {2.4212380706095346e-01,-1.2232505839045147e+00,1.5452602553351020e+00,4.3586652150845900e-01},
3153ca35412SEmil Constantinescu           b2[4] = {3.7810903145819369e-01,-9.6042292212423178e-02,5.0000000000000000e-01,2.1793326075422950e-01};
3163ca35412SEmil Constantinescu 
3173ca35412SEmil Constantinescu           binterpt[0][0]=1.0564298455794094;
3183ca35412SEmil Constantinescu           binterpt[1][0]=2.296429974281067;
3193ca35412SEmil Constantinescu           binterpt[2][0]=-1.307599564525376;
3203ca35412SEmil Constantinescu           binterpt[3][0]=-1.045260255335102;
3213ca35412SEmil Constantinescu           binterpt[0][1]=-1.3864882699759573;
3223ca35412SEmil Constantinescu           binterpt[1][1]=-8.262611700275677;
3233ca35412SEmil Constantinescu           binterpt[2][1]=7.250979895056055;
3243ca35412SEmil Constantinescu           binterpt[3][1]=2.398120075195581;
3253ca35412SEmil Constantinescu           binterpt[0][2]=0.5721822314575016;
3263ca35412SEmil Constantinescu           binterpt[1][2]=4.742931142090097;
3273ca35412SEmil Constantinescu           binterpt[2][2]=-4.398120075195578;
3283ca35412SEmil Constantinescu           binterpt[3][2]=-0.9169932983520199;
3293ca35412SEmil Constantinescu 
3303ca35412SEmil Constantinescu           ierr = TSRosWRegister(TSROSWRA34PW2,3,4,&A[0][0],&Gamma[0][0],b,b2,3,&binterpt[0][0]);CHKERRQ(ierr);
331e27a552bSJed Brown   }
332ef3c5b88SJed Brown   {
333ef3c5b88SJed Brown     const PetscReal g = 0.5;
334ef3c5b88SJed Brown     const PetscReal
335ef3c5b88SJed Brown       A[4][4] = {{0,0,0,0},
336ef3c5b88SJed Brown                  {0,0,0,0},
337ef3c5b88SJed Brown                  {1.,0,0,0},
338ef3c5b88SJed Brown                  {0.75,-0.25,0.5,0}},
339ef3c5b88SJed Brown       Gamma[4][4] = {{g,0,0,0},
340ef3c5b88SJed Brown                      {1.,g,0,0},
341ef3c5b88SJed Brown                      {-0.25,-0.25,g,0},
342ef3c5b88SJed Brown                      {1./12,1./12,-2./3,g}},
343ef3c5b88SJed Brown       b[4] = {5./6,-1./6,-1./6,0.5},
344ef3c5b88SJed Brown       b2[4] = {0.75,-0.25,0.5,0};
345f4aed992SEmil Constantinescu     ierr = TSRosWRegister(TSROSWRODAS3,3,4,&A[0][0],&Gamma[0][0],b,b2,0,PETSC_NULL);CHKERRQ(ierr);
346ef3c5b88SJed Brown   }
347ef3c5b88SJed Brown   {
348ef3c5b88SJed Brown     const PetscReal g = 0.43586652150845899941601945119356;
349ef3c5b88SJed Brown     const PetscReal
350ef3c5b88SJed Brown       A[3][3] = {{0,0,0},
351ef3c5b88SJed Brown                  {g,0,0},
352ef3c5b88SJed Brown                  {g,0,0}},
353ef3c5b88SJed Brown       Gamma[3][3] = {{g,0,0},
354ef3c5b88SJed Brown                      {-0.19294655696029095575009695436041,g,0},
355ef3c5b88SJed Brown                      {0,1.74927148125794685173529749738960,g}},
356ef3c5b88SJed Brown       b[3] = {-0.75457412385404315829818998646589,1.94100407061964420292840123379419,-0.18642994676560104463021124732829},
357ef3c5b88SJed Brown       b2[3] = {-1.53358745784149585370766523913002,2.81745131148625772213931745457622,-0.28386385364476186843165221544619};
358*1f80e275SEmil Constantinescu 
359*1f80e275SEmil Constantinescu       PetscReal  binterpt[3][2];
360*1f80e275SEmil Constantinescu       binterpt[0][0]=3.793692883777660870425141387941;
361*1f80e275SEmil Constantinescu       binterpt[1][0]=-2.918692883777660870425141387941;
362*1f80e275SEmil Constantinescu       binterpt[2][0]=0.125;
363*1f80e275SEmil Constantinescu       binterpt[0][1]=-0.725741064379812106687651020584;
364*1f80e275SEmil Constantinescu       binterpt[1][1]=0.559074397713145440020984353917;
365*1f80e275SEmil Constantinescu       binterpt[2][1]=0.16666666666666666666666666666667;
366*1f80e275SEmil Constantinescu 
367*1f80e275SEmil Constantinescu       ierr = TSRosWRegister(TSROSWSANDU3,3,3,&A[0][0],&Gamma[0][0],b,b2,2,&binterpt[0][0]);CHKERRQ(ierr);
368ef3c5b88SJed Brown   }
369b1c69cc3SEmil Constantinescu   {
370aaf9cf16SJed Brown     const PetscReal s3 = PetscSqrtReal(3.),g = (3.0+s3)/6.0;
371b1c69cc3SEmil Constantinescu     const PetscReal
372b1c69cc3SEmil Constantinescu       A[3][3] = {{0,0,0},
373b1c69cc3SEmil Constantinescu                  {1,0,0},
374b1c69cc3SEmil Constantinescu                  {0.25,0.25,0}},
375b1c69cc3SEmil Constantinescu       Gamma[3][3] = {{0,0,0},
376aaf9cf16SJed Brown                      {(-3.0-s3)/6.0,g,0},
377aaf9cf16SJed Brown                      {(-3.0-s3)/24.0,(-3.0-s3)/8.0,g}},
378b1c69cc3SEmil Constantinescu         b[3] = {1./6.,1./6.,2./3.},
379b1c69cc3SEmil Constantinescu           b2[3] = {1./4.,1./4.,1./2.};
380f4aed992SEmil Constantinescu     ierr = TSRosWRegister(TSROSWASSP3P3S1C,3,3,&A[0][0],&Gamma[0][0],b,b2,0,PETSC_NULL);CHKERRQ(ierr);
381b1c69cc3SEmil Constantinescu   }
382b1c69cc3SEmil Constantinescu 
383b1c69cc3SEmil Constantinescu   {
384b1c69cc3SEmil Constantinescu     const PetscReal
385b1c69cc3SEmil Constantinescu       A[4][4] = {{0,0,0,0},
386b1c69cc3SEmil Constantinescu                  {1./2.,0,0,0},
387b1c69cc3SEmil Constantinescu                  {1./2.,1./2.,0,0},
388b1c69cc3SEmil Constantinescu                  {1./6.,1./6.,1./6.,0}},
389b1c69cc3SEmil Constantinescu       Gamma[4][4] = {{1./2.,0,0,0},
390b1c69cc3SEmil Constantinescu                      {0.0,1./4.,0,0},
391b1c69cc3SEmil Constantinescu                      {-2.,-2./3.,2./3.,0},
392b1c69cc3SEmil Constantinescu                      {1./2.,5./36.,-2./9,0}},
393b1c69cc3SEmil Constantinescu         b[4] = {1./6.,1./6.,1./6.,1./2.},
394b1c69cc3SEmil Constantinescu         b2[4] = {1./8.,3./4.,1./8.,0};
395f4aed992SEmil Constantinescu      ierr = TSRosWRegister(TSROSWLASSP3P4S2C,3,4,&A[0][0],&Gamma[0][0],b,b2,0,PETSC_NULL);CHKERRQ(ierr);
396b1c69cc3SEmil Constantinescu   }
397b1c69cc3SEmil Constantinescu 
398b1c69cc3SEmil Constantinescu   {
399b1c69cc3SEmil Constantinescu     const PetscReal
400b1c69cc3SEmil Constantinescu       A[4][4] = {{0,0,0,0},
401b1c69cc3SEmil Constantinescu                  {1./2.,0,0,0},
402b1c69cc3SEmil Constantinescu                  {1./2.,1./2.,0,0},
403b1c69cc3SEmil Constantinescu                  {1./6.,1./6.,1./6.,0}},
404b1c69cc3SEmil Constantinescu       Gamma[4][4] = {{1./2.,0,0,0},
405b1c69cc3SEmil Constantinescu                      {0.0,3./4.,0,0},
406b1c69cc3SEmil Constantinescu                      {-2./3.,-23./9.,2./9.,0},
407b1c69cc3SEmil Constantinescu                      {1./18.,65./108.,-2./27,0}},
408b1c69cc3SEmil Constantinescu         b[4] = {1./6.,1./6.,1./6.,1./2.},
409b1c69cc3SEmil Constantinescu         b2[4] = {3./16.,10./16.,3./16.,0};
410f4aed992SEmil Constantinescu      ierr = TSRosWRegister(TSROSWLLSSP3P4S2C,3,4,&A[0][0],&Gamma[0][0],b,b2,0,PETSC_NULL);CHKERRQ(ierr);
411b1c69cc3SEmil Constantinescu   }
412753f8adbSEmil Constantinescu 
413753f8adbSEmil Constantinescu  {
414753f8adbSEmil Constantinescu    PetscReal A[4][4],Gamma[4][4],b[4],b2[4];
4153ca35412SEmil Constantinescu    PetscReal  binterpt[4][3];
416753f8adbSEmil Constantinescu 
417753f8adbSEmil Constantinescu    Gamma[0][0]=0.4358665215084589994160194475295062513822671686978816;
41805e8e825SJed Brown    Gamma[0][1]=0; Gamma[0][2]=0; Gamma[0][3]=0;
419753f8adbSEmil Constantinescu    Gamma[1][0]=-1.997527830934941248426324674704153457289527280554476;
420753f8adbSEmil Constantinescu    Gamma[1][1]=0.4358665215084589994160194475295062513822671686978816;
42105e8e825SJed Brown    Gamma[1][2]=0; Gamma[1][3]=0;
422753f8adbSEmil Constantinescu    Gamma[2][0]=-1.007948511795029620852002345345404191008352770119903;
423753f8adbSEmil Constantinescu    Gamma[2][1]=-0.004648958462629345562774289390054679806993396798458131;
424753f8adbSEmil Constantinescu    Gamma[2][2]=0.4358665215084589994160194475295062513822671686978816;
42505e8e825SJed Brown    Gamma[2][3]=0;
426753f8adbSEmil Constantinescu    Gamma[3][0]=-0.6685429734233467180451604600279552604364311322650783;
427753f8adbSEmil Constantinescu    Gamma[3][1]=0.6056625986449338476089525334450053439525178740492984;
428753f8adbSEmil Constantinescu    Gamma[3][2]=-0.9717899277217721234705114616271378792182450260943198;
429753f8adbSEmil Constantinescu    Gamma[3][3]=0;
430753f8adbSEmil Constantinescu 
43105e8e825SJed Brown    A[0][0]=0; A[0][1]=0; A[0][2]=0; A[0][3]=0;
432753f8adbSEmil Constantinescu    A[1][0]=0.8717330430169179988320388950590125027645343373957631;
43305e8e825SJed Brown    A[1][1]=0; A[1][2]=0; A[1][3]=0;
434753f8adbSEmil Constantinescu    A[2][0]=0.5275890119763004115618079766722914408876108660811028;
435753f8adbSEmil Constantinescu    A[2][1]=0.07241098802369958843819203208518599088698057726988732;
43605e8e825SJed Brown    A[2][2]=0; A[2][3]=0;
437753f8adbSEmil Constantinescu    A[3][0]=0.3990960076760701320627260685975778145384666450351314;
438753f8adbSEmil Constantinescu    A[3][1]=-0.4375576546135194437228463747348862825846903771419953;
439753f8adbSEmil Constantinescu    A[3][2]=1.038461646937449311660120300601880176655352737312713;
44005e8e825SJed Brown    A[3][3]=0;
441753f8adbSEmil Constantinescu 
442753f8adbSEmil Constantinescu    b[0]=0.1876410243467238251612921333138006734899663569186926;
443753f8adbSEmil Constantinescu    b[1]=-0.5952974735769549480478230473706443582188442040780541;
444753f8adbSEmil Constantinescu    b[2]=0.9717899277217721234705114616271378792182450260943198;
445753f8adbSEmil Constantinescu    b[3]=0.4358665215084589994160194475295062513822671686978816;
446753f8adbSEmil Constantinescu 
447753f8adbSEmil Constantinescu    b2[0]=0.2147402862233891404862383521089097657790734483804460;
448753f8adbSEmil Constantinescu    b2[1]=-0.4851622638849390928209050538171743017757490232519684;
449753f8adbSEmil Constantinescu    b2[2]=0.8687250025203875511662123688667549217531982787600080;
450753f8adbSEmil Constantinescu    b2[3]=0.4016969751411624011684543450940068201770721128357014;
451753f8adbSEmil Constantinescu 
4523ca35412SEmil Constantinescu    binterpt[0][0]=2.2565812720167954547104627844105;
4533ca35412SEmil Constantinescu    binterpt[1][0]=1.349166413351089573796243820819;
4543ca35412SEmil Constantinescu    binterpt[2][0]=-2.4695174540533503758652847586647;
4553ca35412SEmil Constantinescu    binterpt[3][0]=-0.13623023131453465264142184656474;
4563ca35412SEmil Constantinescu    binterpt[0][1]=-3.0826699111559187902922463354557;
4573ca35412SEmil Constantinescu    binterpt[1][1]=-2.4689115685996042534544925650515;
4583ca35412SEmil Constantinescu    binterpt[2][1]=5.7428279814696677152129332773553;
4593ca35412SEmil Constantinescu    binterpt[3][1]=-0.19124650171414467146619437684812;
4603ca35412SEmil Constantinescu    binterpt[0][2]=1.0137296634858471607430756831148;
4613ca35412SEmil Constantinescu    binterpt[1][2]=0.52444768167155973161042570784064;
4623ca35412SEmil Constantinescu    binterpt[2][2]=-2.3015205996945452158771370439586;
4633ca35412SEmil Constantinescu    binterpt[3][2]=0.76334325453713832352363565300308;
464f4aed992SEmil Constantinescu 
465f73f8d2cSSatish Balay    ierr = TSRosWRegister(TSROSWARK3,3,4,&A[0][0],&Gamma[0][0],b,b2,3,&binterpt[0][0]);CHKERRQ(ierr);
466753f8adbSEmil Constantinescu   }
467753f8adbSEmil Constantinescu 
468e27a552bSJed Brown   PetscFunctionReturn(0);
469e27a552bSJed Brown }
470e27a552bSJed Brown 
471e27a552bSJed Brown #undef __FUNCT__
472e27a552bSJed Brown #define __FUNCT__ "TSRosWRegisterDestroy"
473e27a552bSJed Brown /*@C
474e27a552bSJed Brown    TSRosWRegisterDestroy - Frees the list of schemes that were registered by TSRosWRegister().
475e27a552bSJed Brown 
476e27a552bSJed Brown    Not Collective
477e27a552bSJed Brown 
478e27a552bSJed Brown    Level: advanced
479e27a552bSJed Brown 
480e27a552bSJed Brown .keywords: TSRosW, register, destroy
481e27a552bSJed Brown .seealso: TSRosWRegister(), TSRosWRegisterAll(), TSRosWRegisterDynamic()
482e27a552bSJed Brown @*/
483e27a552bSJed Brown PetscErrorCode TSRosWRegisterDestroy(void)
484e27a552bSJed Brown {
485e27a552bSJed Brown   PetscErrorCode ierr;
48661692a83SJed Brown   RosWTableauLink link;
487e27a552bSJed Brown 
488e27a552bSJed Brown   PetscFunctionBegin;
48961692a83SJed Brown   while ((link = RosWTableauList)) {
49061692a83SJed Brown     RosWTableau t = &link->tab;
49161692a83SJed Brown     RosWTableauList = link->next;
49261692a83SJed Brown     ierr = PetscFree5(t->A,t->Gamma,t->b,t->ASum,t->GammaSum);CHKERRQ(ierr);
49343b21953SEmil Constantinescu     ierr = PetscFree5(t->At,t->bt,t->GammaInv,t->GammaZeroDiag,t->GammaExplicitCorr);CHKERRQ(ierr);
494fe7e6d57SJed Brown     ierr = PetscFree2(t->bembed,t->bembedt);CHKERRQ(ierr);
495f4aed992SEmil Constantinescu     ierr = PetscFree(t->binterpt);CHKERRQ(ierr);
496e27a552bSJed Brown     ierr = PetscFree(t->name);CHKERRQ(ierr);
497e27a552bSJed Brown     ierr = PetscFree(link);CHKERRQ(ierr);
498e27a552bSJed Brown   }
499e27a552bSJed Brown   TSRosWRegisterAllCalled = PETSC_FALSE;
500e27a552bSJed Brown   PetscFunctionReturn(0);
501e27a552bSJed Brown }
502e27a552bSJed Brown 
503e27a552bSJed Brown #undef __FUNCT__
504e27a552bSJed Brown #define __FUNCT__ "TSRosWInitializePackage"
505e27a552bSJed Brown /*@C
506e27a552bSJed Brown   TSRosWInitializePackage - This function initializes everything in the TSRosW package. It is called
507e27a552bSJed Brown   from PetscDLLibraryRegister() when using dynamic libraries, and on the first call to TSCreate_RosW()
508e27a552bSJed Brown   when using static libraries.
509e27a552bSJed Brown 
510e27a552bSJed Brown   Input Parameter:
511e27a552bSJed Brown   path - The dynamic library path, or PETSC_NULL
512e27a552bSJed Brown 
513e27a552bSJed Brown   Level: developer
514e27a552bSJed Brown 
515e27a552bSJed Brown .keywords: TS, TSRosW, initialize, package
516e27a552bSJed Brown .seealso: PetscInitialize()
517e27a552bSJed Brown @*/
518e27a552bSJed Brown PetscErrorCode TSRosWInitializePackage(const char path[])
519e27a552bSJed Brown {
520e27a552bSJed Brown   PetscErrorCode ierr;
521e27a552bSJed Brown 
522e27a552bSJed Brown   PetscFunctionBegin;
523e27a552bSJed Brown   if (TSRosWPackageInitialized) PetscFunctionReturn(0);
524e27a552bSJed Brown   TSRosWPackageInitialized = PETSC_TRUE;
525e27a552bSJed Brown   ierr = TSRosWRegisterAll();CHKERRQ(ierr);
526e27a552bSJed Brown   ierr = PetscRegisterFinalize(TSRosWFinalizePackage);CHKERRQ(ierr);
527e27a552bSJed Brown   PetscFunctionReturn(0);
528e27a552bSJed Brown }
529e27a552bSJed Brown 
530e27a552bSJed Brown #undef __FUNCT__
531e27a552bSJed Brown #define __FUNCT__ "TSRosWFinalizePackage"
532e27a552bSJed Brown /*@C
533e27a552bSJed Brown   TSRosWFinalizePackage - This function destroys everything in the TSRosW package. It is
534e27a552bSJed Brown   called from PetscFinalize().
535e27a552bSJed Brown 
536e27a552bSJed Brown   Level: developer
537e27a552bSJed Brown 
538e27a552bSJed Brown .keywords: Petsc, destroy, package
539e27a552bSJed Brown .seealso: PetscFinalize()
540e27a552bSJed Brown @*/
541e27a552bSJed Brown PetscErrorCode TSRosWFinalizePackage(void)
542e27a552bSJed Brown {
543e27a552bSJed Brown   PetscErrorCode ierr;
544e27a552bSJed Brown 
545e27a552bSJed Brown   PetscFunctionBegin;
546e27a552bSJed Brown   TSRosWPackageInitialized = PETSC_FALSE;
547e27a552bSJed Brown   ierr = TSRosWRegisterDestroy();CHKERRQ(ierr);
548e27a552bSJed Brown   PetscFunctionReturn(0);
549e27a552bSJed Brown }
550e27a552bSJed Brown 
551e27a552bSJed Brown #undef __FUNCT__
552e27a552bSJed Brown #define __FUNCT__ "TSRosWRegister"
553e27a552bSJed Brown /*@C
55461692a83SJed Brown    TSRosWRegister - register a Rosenbrock W scheme by providing the entries in the Butcher tableau and optionally embedded approximations and interpolation
555e27a552bSJed Brown 
556e27a552bSJed Brown    Not Collective, but the same schemes should be registered on all processes on which they will be used
557e27a552bSJed Brown 
558e27a552bSJed Brown    Input Parameters:
559e27a552bSJed Brown +  name - identifier for method
560e27a552bSJed Brown .  order - approximation order of method
561e27a552bSJed Brown .  s - number of stages, this is the dimension of the matrices below
56261692a83SJed Brown .  A - Table of propagated stage coefficients (dimension s*s, row-major), strictly lower triangular
56361692a83SJed Brown .  Gamma - Table of coefficients in implicit stage equations (dimension s*s, row-major), lower triangular with nonzero diagonal
564fe7e6d57SJed Brown .  b - Step completion table (dimension s)
565fe7e6d57SJed Brown -  bembed - Step completion table for a scheme of order one less (dimension s, PETSC_NULL if no embedded scheme is available)
566f4aed992SEmil Constantinescu .  pinterp - Order of the interpolation scheme, equal to the number of columns of binterpt
567f4aed992SEmil Constantinescu .  binterpt - Coefficients of the interpolation formula (dimension s*pinterp)
568e27a552bSJed Brown 
569e27a552bSJed Brown    Notes:
57061692a83SJed Brown    Several Rosenbrock W methods are provided, this function is only needed to create new methods.
571e27a552bSJed Brown 
572e27a552bSJed Brown    Level: advanced
573e27a552bSJed Brown 
574e27a552bSJed Brown .keywords: TS, register
575e27a552bSJed Brown 
576e27a552bSJed Brown .seealso: TSRosW
577e27a552bSJed Brown @*/
578e27a552bSJed Brown PetscErrorCode TSRosWRegister(const TSRosWType name,PetscInt order,PetscInt s,
579f4aed992SEmil Constantinescu                               const PetscReal A[],const PetscReal Gamma[],const PetscReal b[],const PetscReal bembed[],
580f4aed992SEmil Constantinescu                                  PetscInt pinterp,const PetscReal binterpt[])
581e27a552bSJed Brown {
582e27a552bSJed Brown   PetscErrorCode ierr;
58361692a83SJed Brown   RosWTableauLink link;
58461692a83SJed Brown   RosWTableau t;
58561692a83SJed Brown   PetscInt i,j,k;
58661692a83SJed Brown   PetscScalar *GammaInv;
587e27a552bSJed Brown 
588e27a552bSJed Brown   PetscFunctionBegin;
589fe7e6d57SJed Brown   PetscValidCharPointer(name,1);
590fe7e6d57SJed Brown   PetscValidPointer(A,4);
591fe7e6d57SJed Brown   PetscValidPointer(Gamma,5);
592fe7e6d57SJed Brown   PetscValidPointer(b,6);
593fe7e6d57SJed Brown   if (bembed) PetscValidPointer(bembed,7);
594fe7e6d57SJed Brown 
595e27a552bSJed Brown   ierr = PetscMalloc(sizeof(*link),&link);CHKERRQ(ierr);
596e27a552bSJed Brown   ierr = PetscMemzero(link,sizeof(*link));CHKERRQ(ierr);
597e27a552bSJed Brown   t = &link->tab;
598e27a552bSJed Brown   ierr = PetscStrallocpy(name,&t->name);CHKERRQ(ierr);
599e27a552bSJed Brown   t->order = order;
600e27a552bSJed Brown   t->s = s;
60161692a83SJed 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);
60243b21953SEmil 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);
603e27a552bSJed Brown   ierr = PetscMemcpy(t->A,A,s*s*sizeof(A[0]));CHKERRQ(ierr);
60461692a83SJed Brown   ierr = PetscMemcpy(t->Gamma,Gamma,s*s*sizeof(Gamma[0]));CHKERRQ(ierr);
60543b21953SEmil Constantinescu   ierr = PetscMemcpy(t->GammaExplicitCorr,Gamma,s*s*sizeof(Gamma[0]));CHKERRQ(ierr);
60661692a83SJed Brown   ierr = PetscMemcpy(t->b,b,s*sizeof(b[0]));CHKERRQ(ierr);
607fe7e6d57SJed Brown   if (bembed) {
608fe7e6d57SJed Brown     ierr = PetscMalloc2(s,PetscReal,&t->bembed,s,PetscReal,&t->bembedt);CHKERRQ(ierr);
609fe7e6d57SJed Brown     ierr = PetscMemcpy(t->bembed,bembed,s*sizeof(bembed[0]));CHKERRQ(ierr);
610fe7e6d57SJed Brown   }
61161692a83SJed Brown   for (i=0; i<s; i++) {
61261692a83SJed Brown     t->ASum[i] = 0;
61361692a83SJed Brown     t->GammaSum[i] = 0;
61461692a83SJed Brown     for (j=0; j<s; j++) {
61561692a83SJed Brown       t->ASum[i] += A[i*s+j];
616fe7e6d57SJed Brown       t->GammaSum[i] += Gamma[i*s+j];
61761692a83SJed Brown     }
61861692a83SJed Brown   }
61961692a83SJed Brown   ierr = PetscMalloc(s*s*sizeof(PetscScalar),&GammaInv);CHKERRQ(ierr); /* Need to use Scalar for inverse, then convert back to Real */
62061692a83SJed Brown   for (i=0; i<s*s; i++) GammaInv[i] = Gamma[i];
621fd96d5b0SEmil Constantinescu   for (i=0; i<s; i++) {
622fd96d5b0SEmil Constantinescu     if (Gamma[i*s+i] == 0.0) {
623fd96d5b0SEmil Constantinescu       GammaInv[i*s+i] = 1.0;
624c17803e7SJed Brown       t->GammaZeroDiag[i] = PETSC_TRUE;
625fd96d5b0SEmil Constantinescu     } else {
626c17803e7SJed Brown       t->GammaZeroDiag[i] = PETSC_FALSE;
627fd96d5b0SEmil Constantinescu     }
628fd96d5b0SEmil Constantinescu   }
629fd96d5b0SEmil Constantinescu 
63061692a83SJed Brown   switch (s) {
63161692a83SJed Brown   case 1: GammaInv[0] = 1./GammaInv[0]; break;
63261692a83SJed Brown   case 2: ierr = Kernel_A_gets_inverse_A_2(GammaInv,0);CHKERRQ(ierr); break;
63361692a83SJed Brown   case 3: ierr = Kernel_A_gets_inverse_A_3(GammaInv,0);CHKERRQ(ierr); break;
63461692a83SJed Brown   case 4: ierr = Kernel_A_gets_inverse_A_4(GammaInv,0);CHKERRQ(ierr); break;
63561692a83SJed Brown   case 5: {
63661692a83SJed Brown     PetscInt ipvt5[5];
63761692a83SJed Brown     MatScalar work5[5*5];
63861692a83SJed Brown     ierr = Kernel_A_gets_inverse_A_5(GammaInv,ipvt5,work5,0);CHKERRQ(ierr); break;
63961692a83SJed Brown   }
64061692a83SJed Brown   case 6: ierr = Kernel_A_gets_inverse_A_6(GammaInv,0);CHKERRQ(ierr); break;
64161692a83SJed Brown   case 7: ierr = Kernel_A_gets_inverse_A_7(GammaInv,0);CHKERRQ(ierr); break;
64261692a83SJed Brown   default: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented for %D stages",s);
64361692a83SJed Brown   }
64461692a83SJed Brown   for (i=0; i<s*s; i++) t->GammaInv[i] = PetscRealPart(GammaInv[i]);
64561692a83SJed Brown   ierr = PetscFree(GammaInv);CHKERRQ(ierr);
64643b21953SEmil Constantinescu 
64743b21953SEmil Constantinescu   for (i=0; i<s; i++) {
64843b21953SEmil Constantinescu     for (k=0; k<i+1; k++) {
64943b21953SEmil Constantinescu       t->GammaExplicitCorr[i*s+k]=(t->GammaExplicitCorr[i*s+k])*(t->GammaInv[k*s+k]);
65043b21953SEmil Constantinescu       for (j=k+1; j<i+1; j++) {
65143b21953SEmil Constantinescu         t->GammaExplicitCorr[i*s+k]+=(t->GammaExplicitCorr[i*s+j])*(t->GammaInv[j*s+k]);
65243b21953SEmil Constantinescu       }
65343b21953SEmil Constantinescu     }
65443b21953SEmil Constantinescu   }
65543b21953SEmil Constantinescu 
65661692a83SJed Brown   for (i=0; i<s; i++) {
65761692a83SJed Brown     for (j=0; j<s; j++) {
65861692a83SJed Brown       t->At[i*s+j] = 0;
65961692a83SJed Brown       for (k=0; k<s; k++) {
66061692a83SJed Brown         t->At[i*s+j] += t->A[i*s+k] * t->GammaInv[k*s+j];
66161692a83SJed Brown       }
66261692a83SJed Brown     }
66361692a83SJed Brown     t->bt[i] = 0;
66461692a83SJed Brown     for (j=0; j<s; j++) {
66561692a83SJed Brown       t->bt[i] += t->b[j] * t->GammaInv[j*s+i];
66661692a83SJed Brown     }
667fe7e6d57SJed Brown     if (bembed) {
668fe7e6d57SJed Brown       t->bembedt[i] = 0;
669fe7e6d57SJed Brown       for (j=0; j<s; j++) {
670fe7e6d57SJed Brown         t->bembedt[i] += t->bembed[j] * t->GammaInv[j*s+i];
671fe7e6d57SJed Brown       }
672fe7e6d57SJed Brown     }
67361692a83SJed Brown   }
6748d59e960SJed Brown   t->ccfl = 1.0;                /* Fix this */
6758d59e960SJed Brown 
676f4aed992SEmil Constantinescu   t->pinterp = pinterp;
6773ca35412SEmil Constantinescu   ierr = PetscMalloc(s*pinterp*sizeof(binterpt[0]),&t->binterpt);CHKERRQ(ierr);
6783ca35412SEmil Constantinescu   ierr = PetscMemcpy(t->binterpt,binterpt,s*pinterp*sizeof(binterpt[0]));CHKERRQ(ierr);
67961692a83SJed Brown   link->next = RosWTableauList;
68061692a83SJed Brown   RosWTableauList = link;
681e27a552bSJed Brown   PetscFunctionReturn(0);
682e27a552bSJed Brown }
683e27a552bSJed Brown 
684e27a552bSJed Brown #undef __FUNCT__
6851c3436cfSJed Brown #define __FUNCT__ "TSEvaluateStep_RosW"
6861c3436cfSJed Brown /*
6871c3436cfSJed Brown  The step completion formula is
6881c3436cfSJed Brown 
6891c3436cfSJed Brown  x1 = x0 + b^T Y
6901c3436cfSJed Brown 
6911c3436cfSJed Brown  where Y is the multi-vector of stages corrections. This function can be called before or after ts->vec_sol has been
6921c3436cfSJed Brown  updated. Suppose we have a completion formula b and an embedded formula be of different order. We can write
6931c3436cfSJed Brown 
6941c3436cfSJed Brown  x1e = x0 + be^T Y
6951c3436cfSJed Brown      = x1 - b^T Y + be^T Y
6961c3436cfSJed Brown      = x1 + (be - b)^T Y
6971c3436cfSJed Brown 
6981c3436cfSJed Brown  so we can evaluate the method of different order even after the step has been optimistically completed.
6991c3436cfSJed Brown */
7001c3436cfSJed Brown static PetscErrorCode TSEvaluateStep_RosW(TS ts,PetscInt order,Vec X,PetscBool *done)
7011c3436cfSJed Brown {
7021c3436cfSJed Brown   TS_RosW        *ros = (TS_RosW*)ts->data;
7031c3436cfSJed Brown   RosWTableau    tab  = ros->tableau;
7041c3436cfSJed Brown   PetscScalar    *w = ros->work;
7051c3436cfSJed Brown   PetscInt       i;
7061c3436cfSJed Brown   PetscErrorCode ierr;
7071c3436cfSJed Brown 
7081c3436cfSJed Brown   PetscFunctionBegin;
7091c3436cfSJed Brown   if (order == tab->order) {
710108c343cSJed Brown     if (ros->status == TS_STEP_INCOMPLETE) { /* Use standard completion formula */
7111c3436cfSJed Brown       ierr = VecCopy(ts->vec_sol,X);CHKERRQ(ierr);
712de19f811SJed Brown       for (i=0; i<tab->s; i++) w[i] = tab->bt[i];
713de19f811SJed Brown       ierr = VecMAXPY(X,tab->s,w,ros->Y);CHKERRQ(ierr);
714108c343cSJed Brown     } else {ierr = VecCopy(ts->vec_sol,X);CHKERRQ(ierr);}
7151c3436cfSJed Brown     if (done) *done = PETSC_TRUE;
7161c3436cfSJed Brown     PetscFunctionReturn(0);
7171c3436cfSJed Brown   } else if (order == tab->order-1) {
7181c3436cfSJed Brown     if (!tab->bembedt) goto unavailable;
719108c343cSJed Brown     if (ros->status == TS_STEP_INCOMPLETE) { /* Use embedded completion formula */
7201c3436cfSJed Brown       ierr = VecCopy(ts->vec_sol,X);CHKERRQ(ierr);
721de19f811SJed Brown       for (i=0; i<tab->s; i++) w[i] = tab->bembedt[i];
722de19f811SJed Brown       ierr = VecMAXPY(X,tab->s,w,ros->Y);CHKERRQ(ierr);
723108c343cSJed Brown     } else {                    /* Use rollback-and-recomplete formula (bembedt - bt) */
724108c343cSJed Brown       for (i=0; i<tab->s; i++) w[i] = tab->bembedt[i] - tab->bt[i];
725108c343cSJed Brown       ierr = VecCopy(ts->vec_sol,X);CHKERRQ(ierr);
726108c343cSJed Brown       ierr = VecMAXPY(X,tab->s,w,ros->Y);CHKERRQ(ierr);
7271c3436cfSJed Brown     }
7281c3436cfSJed Brown     if (done) *done = PETSC_TRUE;
7291c3436cfSJed Brown     PetscFunctionReturn(0);
7301c3436cfSJed Brown   }
7311c3436cfSJed Brown   unavailable:
7321c3436cfSJed Brown   if (done) *done = PETSC_FALSE;
7331c3436cfSJed Brown   else SETERRQ3(((PetscObject)ts)->comm,PETSC_ERR_SUP,"Rosenbrock-W '%s' of order %D cannot evaluate step at order %D",tab->name,tab->order,order);
7341c3436cfSJed Brown   PetscFunctionReturn(0);
7351c3436cfSJed Brown }
7361c3436cfSJed Brown 
7371c3436cfSJed Brown #undef __FUNCT__
738e27a552bSJed Brown #define __FUNCT__ "TSStep_RosW"
739e27a552bSJed Brown static PetscErrorCode TSStep_RosW(TS ts)
740e27a552bSJed Brown {
74161692a83SJed Brown   TS_RosW         *ros = (TS_RosW*)ts->data;
74261692a83SJed Brown   RosWTableau     tab  = ros->tableau;
743e27a552bSJed Brown   const PetscInt  s    = tab->s;
7441c3436cfSJed Brown   const PetscReal *At  = tab->At,*Gamma = tab->Gamma,*ASum = tab->ASum,*GammaInv = tab->GammaInv;
7450feba352SEmil Constantinescu   const PetscReal *GammaExplicitCorr = tab->GammaExplicitCorr;
746c17803e7SJed Brown   const PetscBool *GammaZeroDiag = tab->GammaZeroDiag;
74761692a83SJed Brown   PetscScalar     *w   = ros->work;
7487d4bf2deSEmil Constantinescu   Vec             *Y   = ros->Y,Ydot = ros->Ydot,Zdot = ros->Zdot,Zstage = ros->Zstage;
749e27a552bSJed Brown   SNES            snes;
7501c3436cfSJed Brown   TSAdapt         adapt;
7511c3436cfSJed Brown   PetscInt        i,j,its,lits,reject,next_scheme;
752cdbf8f93SLisandro Dalcin   PetscReal       next_time_step;
7531c3436cfSJed Brown   PetscBool       accept;
754e27a552bSJed Brown   PetscErrorCode  ierr;
7550feba352SEmil Constantinescu   MatStructure    str;
756e27a552bSJed Brown 
757e27a552bSJed Brown   PetscFunctionBegin;
758e27a552bSJed Brown   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
759cdbf8f93SLisandro Dalcin   next_time_step = ts->time_step;
7601c3436cfSJed Brown   accept = PETSC_TRUE;
761108c343cSJed Brown   ros->status = TS_STEP_INCOMPLETE;
762e27a552bSJed Brown 
76397335746SJed Brown   for (reject=0; reject<ts->max_reject && !ts->reason; reject++,ts->reject++) {
7641c3436cfSJed Brown     const PetscReal h = ts->time_step;
7653ca35412SEmil Constantinescu     ierr = VecCopy(ts->vec_sol,ros->VecSolPrev);CHKERRQ(ierr);/*move this at the end*/
766e27a552bSJed Brown     for (i=0; i<s; i++) {
7671c3436cfSJed Brown       ros->stage_time = ts->ptime + h*ASum[i];
768c17803e7SJed Brown       if (GammaZeroDiag[i]) {
769c17803e7SJed Brown         ros->stage_explicit = PETSC_TRUE;
770fd96d5b0SEmil Constantinescu         ros->shift = 1./h;
771c17803e7SJed Brown       } else {
772c17803e7SJed Brown         ros->stage_explicit = PETSC_FALSE;
77361692a83SJed Brown         ros->shift = 1./(h*Gamma[i*s+i]);
774fd96d5b0SEmil Constantinescu       }
77561692a83SJed Brown 
77661692a83SJed Brown       ierr = VecCopy(ts->vec_sol,Zstage);CHKERRQ(ierr);
777de19f811SJed Brown       for (j=0; j<i; j++) w[j] = At[i*s+j];
778de19f811SJed Brown       ierr = VecMAXPY(Zstage,i,w,Y);CHKERRQ(ierr);
77961692a83SJed Brown 
78061692a83SJed Brown       for (j=0; j<i; j++) w[j] = 1./h * GammaInv[i*s+j];
78161692a83SJed Brown       ierr = VecZeroEntries(Zdot);CHKERRQ(ierr);
78261692a83SJed Brown       ierr = VecMAXPY(Zdot,i,w,Y);CHKERRQ(ierr);
78361692a83SJed Brown 
784e27a552bSJed Brown       /* Initial guess taken from last stage */
78561692a83SJed Brown       ierr = VecZeroEntries(Y[i]);CHKERRQ(ierr);
78661692a83SJed Brown 
7877d4bf2deSEmil Constantinescu       if (!ros->stage_explicit) {
78861692a83SJed Brown         if (!ros->recompute_jacobian && !i) {
78961692a83SJed Brown           ierr = SNESSetLagJacobian(snes,-2);CHKERRQ(ierr); /* Recompute the Jacobian on this solve, but not again */
79061692a83SJed Brown         }
79161692a83SJed Brown         ierr = SNESSolve(snes,PETSC_NULL,Y[i]);CHKERRQ(ierr);
792e27a552bSJed Brown         ierr = SNESGetIterationNumber(snes,&its);CHKERRQ(ierr);
793e27a552bSJed Brown         ierr = SNESGetLinearSolveIterations(snes,&lits);CHKERRQ(ierr);
794e27a552bSJed Brown         ts->nonlinear_its += its; ts->linear_its += lits;
79597335746SJed Brown         ierr = TSGetAdapt(ts,&adapt);CHKERRQ(ierr);
79697335746SJed Brown         ierr = TSAdaptCheckStage(adapt,ts,&accept);CHKERRQ(ierr);
79797335746SJed Brown         if (!accept) goto reject_step;
7987d4bf2deSEmil Constantinescu       } else {
7991ce71dffSSatish Balay         Mat J,Jp;
8000feba352SEmil Constantinescu         ierr = VecZeroEntries(Ydot);CHKERRQ(ierr); /* Evaluate Y[i]=G(t,Ydot=0,Zstage) */
8010feba352SEmil Constantinescu         ierr = TSComputeIFunction(ts,ros->stage_time,Zstage,Ydot,Y[i],PETSC_FALSE);CHKERRQ(ierr);
8020feba352SEmil Constantinescu         ierr = VecScale(Y[i],-1.0);
8030feba352SEmil Constantinescu         ierr = VecAXPY(Y[i],-1.0,Zdot);CHKERRQ(ierr); /*Y[i]=F(Zstage)-Zdot[=GammaInv*Y]*/
8040feba352SEmil Constantinescu 
8050feba352SEmil Constantinescu         ierr = VecZeroEntries(Zstage);CHKERRQ(ierr); /* Zstage = GammaExplicitCorr[i,j] * Y[j] */
8060feba352SEmil Constantinescu         for (j=0; j<i; j++) w[j] = GammaExplicitCorr[i*s+j];
8070feba352SEmil Constantinescu         ierr = VecMAXPY(Zstage,i,w,Y);CHKERRQ(ierr);
8080feba352SEmil Constantinescu         /*Y[i] += Y[i] + Jac*Zstage[=Jac*GammaExplicitCorr[i,j] * Y[j]] */
8090feba352SEmil Constantinescu         str = SAME_NONZERO_PATTERN;
8100feba352SEmil Constantinescu         ierr = TSGetIJacobian(ts,&J,&Jp,PETSC_NULL,PETSC_NULL);
8110feba352SEmil Constantinescu         ierr = TSComputeIJacobian(ts,ros->stage_time,ts->vec_sol,Ydot,0,&J,&Jp,&str,PETSC_FALSE);CHKERRQ(ierr);
8120feba352SEmil Constantinescu         ierr = MatMult(J,Zstage,Zdot);
8130feba352SEmil Constantinescu 
8140feba352SEmil Constantinescu         ierr = VecAXPY(Y[i],-1.0,Zdot);CHKERRQ(ierr);
8150feba352SEmil Constantinescu         ierr = VecScale(Y[i],h);
8167d4bf2deSEmil Constantinescu         ts->linear_its += 1;
8177d4bf2deSEmil Constantinescu       }
818e27a552bSJed Brown     }
8191c3436cfSJed Brown     ierr = TSEvaluateStep(ts,tab->order,ts->vec_sol,PETSC_NULL);CHKERRQ(ierr);
820108c343cSJed Brown     ros->status = TS_STEP_PENDING;
821e27a552bSJed Brown 
8221c3436cfSJed Brown     /* Register only the current method as a candidate because we're not supporting multiple candidates yet. */
8231c3436cfSJed Brown     ierr = TSGetAdapt(ts,&adapt);CHKERRQ(ierr);
8241c3436cfSJed Brown     ierr = TSAdaptCandidatesClear(adapt);CHKERRQ(ierr);
8258d59e960SJed Brown     ierr = TSAdaptCandidateAdd(adapt,tab->name,tab->order,1,tab->ccfl,1.*tab->s,PETSC_TRUE);CHKERRQ(ierr);
8261c3436cfSJed Brown     ierr = TSAdaptChoose(adapt,ts,ts->time_step,&next_scheme,&next_time_step,&accept);CHKERRQ(ierr);
8271c3436cfSJed Brown     if (accept) {
8281c3436cfSJed Brown       /* ignore next_scheme for now */
829e27a552bSJed Brown       ts->ptime += ts->time_step;
830cdbf8f93SLisandro Dalcin       ts->time_step = next_time_step;
831e27a552bSJed Brown       ts->steps++;
832108c343cSJed Brown       ros->status = TS_STEP_COMPLETE;
8331c3436cfSJed Brown       break;
8341c3436cfSJed Brown     } else {                    /* Roll back the current step */
8351c3436cfSJed Brown       for (i=0; i<s; i++) w[i] = -tab->bt[i];
8361c3436cfSJed Brown       ierr = VecMAXPY(ts->vec_sol,s,w,Y);CHKERRQ(ierr);
8371c3436cfSJed Brown       ts->time_step = next_time_step;
838108c343cSJed Brown       ros->status = TS_STEP_INCOMPLETE;
8391c3436cfSJed Brown     }
840476b6736SJed Brown     reject_step: continue;
8411c3436cfSJed Brown   }
842b2ce242eSJed Brown   if (ros->status != TS_STEP_COMPLETE && !ts->reason) ts->reason = TS_DIVERGED_STEP_REJECTED;
843e27a552bSJed Brown   PetscFunctionReturn(0);
844e27a552bSJed Brown }
845e27a552bSJed Brown 
846e27a552bSJed Brown #undef __FUNCT__
847e27a552bSJed Brown #define __FUNCT__ "TSInterpolate_RosW"
848e27a552bSJed Brown static PetscErrorCode TSInterpolate_RosW(TS ts,PetscReal itime,Vec X)
849e27a552bSJed Brown {
85061692a83SJed Brown   TS_RosW        *ros = (TS_RosW*)ts->data;
851f4aed992SEmil Constantinescu   PetscInt s = ros->tableau->s,pinterp = ros->tableau->pinterp,i,j;
852f4aed992SEmil Constantinescu   PetscReal h;
853f4aed992SEmil Constantinescu   PetscReal tt,t;
854f4aed992SEmil Constantinescu   PetscScalar *bt;
855f4aed992SEmil Constantinescu   const PetscReal *Bt = ros->tableau->binterpt;
856f4aed992SEmil Constantinescu   PetscErrorCode ierr;
857f4aed992SEmil Constantinescu   const PetscReal *GammaInv = ros->tableau->GammaInv;
858f4aed992SEmil Constantinescu   PetscScalar     *w   = ros->work;
859f4aed992SEmil Constantinescu   Vec             *Y   = ros->Y;
860e27a552bSJed Brown 
861e27a552bSJed Brown   PetscFunctionBegin;
862f4aed992SEmil Constantinescu   if (!Bt) SETERRQ1(((PetscObject)ts)->comm,PETSC_ERR_SUP,"TSRosW %s does not have an interpolation formula",ros->tableau->name);
863f4aed992SEmil Constantinescu 
864f4aed992SEmil Constantinescu   switch (ros->status) {
865f4aed992SEmil Constantinescu   case TS_STEP_INCOMPLETE:
866f4aed992SEmil Constantinescu   case TS_STEP_PENDING:
867f4aed992SEmil Constantinescu     h = ts->time_step;
868f4aed992SEmil Constantinescu     t = (itime - ts->ptime)/h;
869f4aed992SEmil Constantinescu     break;
870f4aed992SEmil Constantinescu   case TS_STEP_COMPLETE:
871f4aed992SEmil Constantinescu     h = ts->time_step_prev;
872f4aed992SEmil Constantinescu     t = (itime - ts->ptime)/h + 1; /* In the interval [0,1] */
873f4aed992SEmil Constantinescu     break;
874f4aed992SEmil Constantinescu   default: SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_PLIB,"Invalid TSStepStatus");
875f4aed992SEmil Constantinescu   }
8763ca35412SEmil Constantinescu   ierr = PetscMalloc(s*sizeof(bt[0]),&bt);CHKERRQ(ierr);
877f4aed992SEmil Constantinescu   for (i=0; i<s; i++) bt[i] = 0;
878f4aed992SEmil Constantinescu   for (j=0,tt=t; j<pinterp; j++,tt*=t) {
879f4aed992SEmil Constantinescu     for (i=0; i<s; i++) {
8803ca35412SEmil Constantinescu       bt[i] += Bt[i*pinterp+j] * tt;
881f4aed992SEmil Constantinescu     }
882f4aed992SEmil Constantinescu   }
883f4aed992SEmil Constantinescu 
884f4aed992SEmil Constantinescu   /* y(t+tt*h) = y(t) + Sum bt(tt) * GammaInv * Ydot */
885f4aed992SEmil Constantinescu   /*X<-0*/
886f4aed992SEmil Constantinescu   ierr = VecZeroEntries(X);CHKERRQ(ierr);
887f4aed992SEmil Constantinescu 
888f4aed992SEmil Constantinescu   /*X<- Sum bt_i * GammaInv(i,1:i) * Y(1:i) */
8893ca35412SEmil Constantinescu   for (j=0; j<s; j++)  w[j]=0;
8903ca35412SEmil Constantinescu   for (j=0; j<s; j++) {
8913ca35412SEmil Constantinescu     for (i=j; i<s; i++) {
8923ca35412SEmil Constantinescu       w[j] +=  bt[i]*GammaInv[i*s+j];
893f4aed992SEmil Constantinescu     }
8943ca35412SEmil Constantinescu   }
8953ca35412SEmil Constantinescu   ierr = VecMAXPY(X,i,w,Y);CHKERRQ(ierr);
896f4aed992SEmil Constantinescu 
897f4aed992SEmil Constantinescu   /*X<-y(t) + X*/
8983ca35412SEmil Constantinescu   ierr = VecAXPY(X,1.0,ros->VecSolPrev);CHKERRQ(ierr);
899f4aed992SEmil Constantinescu 
900f4aed992SEmil Constantinescu   ierr = PetscFree(bt);CHKERRQ(ierr);
901f4aed992SEmil Constantinescu 
902e27a552bSJed Brown   PetscFunctionReturn(0);
903e27a552bSJed Brown }
904e27a552bSJed Brown 
905e27a552bSJed Brown /*------------------------------------------------------------*/
906e27a552bSJed Brown #undef __FUNCT__
907e27a552bSJed Brown #define __FUNCT__ "TSReset_RosW"
908e27a552bSJed Brown static PetscErrorCode TSReset_RosW(TS ts)
909e27a552bSJed Brown {
91061692a83SJed Brown   TS_RosW        *ros = (TS_RosW*)ts->data;
911e27a552bSJed Brown   PetscInt       s;
912e27a552bSJed Brown   PetscErrorCode ierr;
913e27a552bSJed Brown 
914e27a552bSJed Brown   PetscFunctionBegin;
91561692a83SJed Brown   if (!ros->tableau) PetscFunctionReturn(0);
91661692a83SJed Brown    s = ros->tableau->s;
91761692a83SJed Brown   ierr = VecDestroyVecs(s,&ros->Y);CHKERRQ(ierr);
91861692a83SJed Brown   ierr = VecDestroy(&ros->Ydot);CHKERRQ(ierr);
91961692a83SJed Brown   ierr = VecDestroy(&ros->Ystage);CHKERRQ(ierr);
92061692a83SJed Brown   ierr = VecDestroy(&ros->Zdot);CHKERRQ(ierr);
92161692a83SJed Brown   ierr = VecDestroy(&ros->Zstage);CHKERRQ(ierr);
9223ca35412SEmil Constantinescu   ierr = VecDestroy(&ros->VecSolPrev);CHKERRQ(ierr);
92361692a83SJed Brown   ierr = PetscFree(ros->work);CHKERRQ(ierr);
924e27a552bSJed Brown   PetscFunctionReturn(0);
925e27a552bSJed Brown }
926e27a552bSJed Brown 
927e27a552bSJed Brown #undef __FUNCT__
928e27a552bSJed Brown #define __FUNCT__ "TSDestroy_RosW"
929e27a552bSJed Brown static PetscErrorCode TSDestroy_RosW(TS ts)
930e27a552bSJed Brown {
931e27a552bSJed Brown   PetscErrorCode  ierr;
932e27a552bSJed Brown 
933e27a552bSJed Brown   PetscFunctionBegin;
934e27a552bSJed Brown   ierr = TSReset_RosW(ts);CHKERRQ(ierr);
935e27a552bSJed Brown   ierr = PetscFree(ts->data);CHKERRQ(ierr);
936e27a552bSJed Brown   ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSRosWGetType_C","",PETSC_NULL);CHKERRQ(ierr);
937e27a552bSJed Brown   ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSRosWSetType_C","",PETSC_NULL);CHKERRQ(ierr);
93861692a83SJed Brown   ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSRosWSetRecomputeJacobian_C","",PETSC_NULL);CHKERRQ(ierr);
939e27a552bSJed Brown   PetscFunctionReturn(0);
940e27a552bSJed Brown }
941e27a552bSJed Brown 
942e27a552bSJed Brown /*
943e27a552bSJed Brown   This defines the nonlinear equation that is to be solved with SNES
944e27a552bSJed Brown   G(U) = F[t0+Theta*dt, U, (U-U0)*shift] = 0
945e27a552bSJed Brown */
946e27a552bSJed Brown #undef __FUNCT__
947e27a552bSJed Brown #define __FUNCT__ "SNESTSFormFunction_RosW"
948e27a552bSJed Brown static PetscErrorCode SNESTSFormFunction_RosW(SNES snes,Vec X,Vec F,TS ts)
949e27a552bSJed Brown {
95061692a83SJed Brown   TS_RosW        *ros = (TS_RosW*)ts->data;
951e27a552bSJed Brown   PetscErrorCode ierr;
952e27a552bSJed Brown 
953e27a552bSJed Brown   PetscFunctionBegin;
95461692a83SJed Brown   ierr = VecWAXPY(ros->Ydot,ros->shift,X,ros->Zdot);CHKERRQ(ierr); /* Ydot = shift*X + Zdot */
95561692a83SJed Brown   ierr = VecWAXPY(ros->Ystage,1.0,X,ros->Zstage);CHKERRQ(ierr);    /* Ystage = X + Zstage */
95661692a83SJed Brown   ierr = TSComputeIFunction(ts,ros->stage_time,ros->Ystage,ros->Ydot,F,PETSC_FALSE);CHKERRQ(ierr);
957e27a552bSJed Brown   PetscFunctionReturn(0);
958e27a552bSJed Brown }
959e27a552bSJed Brown 
960e27a552bSJed Brown #undef __FUNCT__
961e27a552bSJed Brown #define __FUNCT__ "SNESTSFormJacobian_RosW"
962e27a552bSJed Brown static PetscErrorCode SNESTSFormJacobian_RosW(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *str,TS ts)
963e27a552bSJed Brown {
96461692a83SJed Brown   TS_RosW        *ros = (TS_RosW*)ts->data;
965e27a552bSJed Brown   PetscErrorCode ierr;
966e27a552bSJed Brown 
967e27a552bSJed Brown   PetscFunctionBegin;
96861692a83SJed Brown   /* ros->Ydot and ros->Ystage have already been computed in SNESTSFormFunction_RosW (SNES guarantees this) */
96961692a83SJed Brown   ierr = TSComputeIJacobian(ts,ros->stage_time,ros->Ystage,ros->Ydot,ros->shift,A,B,str,PETSC_TRUE);CHKERRQ(ierr);
970e27a552bSJed Brown   PetscFunctionReturn(0);
971e27a552bSJed Brown }
972e27a552bSJed Brown 
973e27a552bSJed Brown #undef __FUNCT__
974e27a552bSJed Brown #define __FUNCT__ "TSSetUp_RosW"
975e27a552bSJed Brown static PetscErrorCode TSSetUp_RosW(TS ts)
976e27a552bSJed Brown {
97761692a83SJed Brown   TS_RosW        *ros = (TS_RosW*)ts->data;
97861692a83SJed Brown   RosWTableau    tab  = ros->tableau;
979e27a552bSJed Brown   PetscInt       s    = tab->s;
980e27a552bSJed Brown   PetscErrorCode ierr;
981e27a552bSJed Brown 
982e27a552bSJed Brown   PetscFunctionBegin;
98361692a83SJed Brown   if (!ros->tableau) {
984e27a552bSJed Brown     ierr = TSRosWSetType(ts,TSRosWDefault);CHKERRQ(ierr);
985e27a552bSJed Brown   }
98661692a83SJed Brown   ierr = VecDuplicateVecs(ts->vec_sol,s,&ros->Y);CHKERRQ(ierr);
98761692a83SJed Brown   ierr = VecDuplicate(ts->vec_sol,&ros->Ydot);CHKERRQ(ierr);
98861692a83SJed Brown   ierr = VecDuplicate(ts->vec_sol,&ros->Ystage);CHKERRQ(ierr);
98961692a83SJed Brown   ierr = VecDuplicate(ts->vec_sol,&ros->Zdot);CHKERRQ(ierr);
99061692a83SJed Brown   ierr = VecDuplicate(ts->vec_sol,&ros->Zstage);CHKERRQ(ierr);
9913ca35412SEmil Constantinescu   ierr = VecDuplicate(ts->vec_sol,&ros->VecSolPrev);CHKERRQ(ierr);
99261692a83SJed Brown   ierr = PetscMalloc(s*sizeof(ros->work[0]),&ros->work);CHKERRQ(ierr);
993e27a552bSJed Brown   PetscFunctionReturn(0);
994e27a552bSJed Brown }
995e27a552bSJed Brown /*------------------------------------------------------------*/
996e27a552bSJed Brown 
997e27a552bSJed Brown #undef __FUNCT__
998e27a552bSJed Brown #define __FUNCT__ "TSSetFromOptions_RosW"
999e27a552bSJed Brown static PetscErrorCode TSSetFromOptions_RosW(TS ts)
1000e27a552bSJed Brown {
100161692a83SJed Brown   TS_RosW        *ros = (TS_RosW*)ts->data;
1002e27a552bSJed Brown   PetscErrorCode ierr;
100361692a83SJed Brown   char           rostype[256];
1004e27a552bSJed Brown 
1005e27a552bSJed Brown   PetscFunctionBegin;
1006e27a552bSJed Brown   ierr = PetscOptionsHead("RosW ODE solver options");CHKERRQ(ierr);
1007e27a552bSJed Brown   {
100861692a83SJed Brown     RosWTableauLink link;
1009e27a552bSJed Brown     PetscInt count,choice;
1010e27a552bSJed Brown     PetscBool flg;
1011e27a552bSJed Brown     const char **namelist;
101261692a83SJed Brown     SNES snes;
101361692a83SJed Brown 
101461692a83SJed Brown     ierr = PetscStrncpy(rostype,TSRosWDefault,sizeof rostype);CHKERRQ(ierr);
101561692a83SJed Brown     for (link=RosWTableauList,count=0; link; link=link->next,count++) ;
1016e27a552bSJed Brown     ierr = PetscMalloc(count*sizeof(char*),&namelist);CHKERRQ(ierr);
101761692a83SJed Brown     for (link=RosWTableauList,count=0; link; link=link->next,count++) namelist[count] = link->tab.name;
101861692a83SJed Brown     ierr = PetscOptionsEList("-ts_rosw_type","Family of Rosenbrock-W method","TSRosWSetType",(const char*const*)namelist,count,rostype,&choice,&flg);CHKERRQ(ierr);
101961692a83SJed Brown     ierr = TSRosWSetType(ts,flg ? namelist[choice] : rostype);CHKERRQ(ierr);
1020e27a552bSJed Brown     ierr = PetscFree(namelist);CHKERRQ(ierr);
102161692a83SJed Brown 
102261692a83SJed Brown     ierr = PetscOptionsBool("-ts_rosw_recompute_jacobian","Recompute the Jacobian at each stage","TSRosWSetRecomputeJacobian",ros->recompute_jacobian,&ros->recompute_jacobian,PETSC_NULL);CHKERRQ(ierr);
102361692a83SJed Brown 
102461692a83SJed Brown     /* Rosenbrock methods are linearly implicit, so set that unless the user has specifically asked for something else */
102561692a83SJed Brown     ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
102661692a83SJed Brown     if (!((PetscObject)snes)->type_name) {
102761692a83SJed Brown       ierr = SNESSetType(snes,SNESKSPONLY);CHKERRQ(ierr);
102861692a83SJed Brown     }
102961692a83SJed Brown     ierr = SNESSetFromOptions(snes);CHKERRQ(ierr);
1030e27a552bSJed Brown   }
1031e27a552bSJed Brown   ierr = PetscOptionsTail();CHKERRQ(ierr);
1032e27a552bSJed Brown   PetscFunctionReturn(0);
1033e27a552bSJed Brown }
1034e27a552bSJed Brown 
1035e27a552bSJed Brown #undef __FUNCT__
1036e27a552bSJed Brown #define __FUNCT__ "PetscFormatRealArray"
1037e27a552bSJed Brown static PetscErrorCode PetscFormatRealArray(char buf[],size_t len,const char *fmt,PetscInt n,const PetscReal x[])
1038e27a552bSJed Brown {
1039e27a552bSJed Brown   PetscErrorCode ierr;
1040e408995aSJed Brown   PetscInt i;
1041e408995aSJed Brown   size_t left,count;
1042e27a552bSJed Brown   char *p;
1043e27a552bSJed Brown 
1044e27a552bSJed Brown   PetscFunctionBegin;
1045e408995aSJed Brown   for (i=0,p=buf,left=len; i<n; i++) {
1046e408995aSJed Brown     ierr = PetscSNPrintfCount(p,left,fmt,&count,x[i]);CHKERRQ(ierr);
1047e27a552bSJed Brown     if (count >= left) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Insufficient space in buffer");
1048e27a552bSJed Brown     left -= count;
1049e27a552bSJed Brown     p += count;
1050e27a552bSJed Brown     *p++ = ' ';
1051e27a552bSJed Brown   }
1052e27a552bSJed Brown   p[i ? 0 : -1] = 0;
1053e27a552bSJed Brown   PetscFunctionReturn(0);
1054e27a552bSJed Brown }
1055e27a552bSJed Brown 
1056e27a552bSJed Brown #undef __FUNCT__
1057e27a552bSJed Brown #define __FUNCT__ "TSView_RosW"
1058e27a552bSJed Brown static PetscErrorCode TSView_RosW(TS ts,PetscViewer viewer)
1059e27a552bSJed Brown {
106061692a83SJed Brown   TS_RosW        *ros = (TS_RosW*)ts->data;
106161692a83SJed Brown   RosWTableau    tab  = ros->tableau;
1062e27a552bSJed Brown   PetscBool      iascii;
1063e27a552bSJed Brown   PetscErrorCode ierr;
1064e27a552bSJed Brown 
1065e27a552bSJed Brown   PetscFunctionBegin;
1066e27a552bSJed Brown   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1067e27a552bSJed Brown   if (iascii) {
106861692a83SJed Brown     const TSRosWType rostype;
1069e408995aSJed Brown     PetscInt i;
1070e408995aSJed Brown     PetscReal abscissa[512];
1071e27a552bSJed Brown     char buf[512];
107261692a83SJed Brown     ierr = TSRosWGetType(ts,&rostype);CHKERRQ(ierr);
107361692a83SJed Brown     ierr = PetscViewerASCIIPrintf(viewer,"  Rosenbrock-W %s\n",rostype);CHKERRQ(ierr);
1074e408995aSJed Brown     ierr = PetscFormatRealArray(buf,sizeof buf,"% 8.6f",tab->s,tab->ASum);CHKERRQ(ierr);
107561692a83SJed Brown     ierr = PetscViewerASCIIPrintf(viewer,"  Abscissa of A       = %s\n",buf);CHKERRQ(ierr);
1076e408995aSJed Brown     for (i=0; i<tab->s; i++) abscissa[i] = tab->ASum[i] + tab->Gamma[i];
1077e408995aSJed Brown     ierr = PetscFormatRealArray(buf,sizeof buf,"% 8.6f",tab->s,abscissa);CHKERRQ(ierr);
1078e408995aSJed Brown     ierr = PetscViewerASCIIPrintf(viewer,"  Abscissa of A+Gamma = %s\n",buf);CHKERRQ(ierr);
1079e27a552bSJed Brown   }
1080e27a552bSJed Brown   ierr = SNESView(ts->snes,viewer);CHKERRQ(ierr);
1081e27a552bSJed Brown   PetscFunctionReturn(0);
1082e27a552bSJed Brown }
1083e27a552bSJed Brown 
1084e27a552bSJed Brown #undef __FUNCT__
1085e27a552bSJed Brown #define __FUNCT__ "TSRosWSetType"
1086e27a552bSJed Brown /*@C
108761692a83SJed Brown   TSRosWSetType - Set the type of Rosenbrock-W scheme
1088e27a552bSJed Brown 
1089e27a552bSJed Brown   Logically collective
1090e27a552bSJed Brown 
1091e27a552bSJed Brown   Input Parameter:
1092e27a552bSJed Brown +  ts - timestepping context
109361692a83SJed Brown -  rostype - type of Rosenbrock-W scheme
1094e27a552bSJed Brown 
1095020d8f30SJed Brown   Level: beginner
1096e27a552bSJed Brown 
1097020d8f30SJed Brown .seealso: TSRosWGetType(), TSROSW, TSROSW2M, TSROSW2P, TSROSWRA3PW, TSROSWRA34PW2, TSROSWRODAS3, TSROSWSANDU3, TSROSWASSP3P3S1C, TSROSWLASSP3P4S2C, TSROSWLLSSP3P4S2C, TSROSWARK3
1098e27a552bSJed Brown @*/
109961692a83SJed Brown PetscErrorCode TSRosWSetType(TS ts,const TSRosWType rostype)
1100e27a552bSJed Brown {
1101e27a552bSJed Brown   PetscErrorCode ierr;
1102e27a552bSJed Brown 
1103e27a552bSJed Brown   PetscFunctionBegin;
1104e27a552bSJed Brown   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
110561692a83SJed Brown   ierr = PetscTryMethod(ts,"TSRosWSetType_C",(TS,const TSRosWType),(ts,rostype));CHKERRQ(ierr);
1106e27a552bSJed Brown   PetscFunctionReturn(0);
1107e27a552bSJed Brown }
1108e27a552bSJed Brown 
1109e27a552bSJed Brown #undef __FUNCT__
1110e27a552bSJed Brown #define __FUNCT__ "TSRosWGetType"
1111e27a552bSJed Brown /*@C
111261692a83SJed Brown   TSRosWGetType - Get the type of Rosenbrock-W scheme
1113e27a552bSJed Brown 
1114e27a552bSJed Brown   Logically collective
1115e27a552bSJed Brown 
1116e27a552bSJed Brown   Input Parameter:
1117e27a552bSJed Brown .  ts - timestepping context
1118e27a552bSJed Brown 
1119e27a552bSJed Brown   Output Parameter:
112061692a83SJed Brown .  rostype - type of Rosenbrock-W scheme
1121e27a552bSJed Brown 
1122e27a552bSJed Brown   Level: intermediate
1123e27a552bSJed Brown 
1124e27a552bSJed Brown .seealso: TSRosWGetType()
1125e27a552bSJed Brown @*/
112661692a83SJed Brown PetscErrorCode TSRosWGetType(TS ts,const TSRosWType *rostype)
1127e27a552bSJed Brown {
1128e27a552bSJed Brown   PetscErrorCode ierr;
1129e27a552bSJed Brown 
1130e27a552bSJed Brown   PetscFunctionBegin;
1131e27a552bSJed Brown   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
113261692a83SJed Brown   ierr = PetscUseMethod(ts,"TSRosWGetType_C",(TS,const TSRosWType*),(ts,rostype));CHKERRQ(ierr);
1133e27a552bSJed Brown   PetscFunctionReturn(0);
1134e27a552bSJed Brown }
1135e27a552bSJed Brown 
1136e27a552bSJed Brown #undef __FUNCT__
113761692a83SJed Brown #define __FUNCT__ "TSRosWSetRecomputeJacobian"
1138e27a552bSJed Brown /*@C
113961692a83SJed Brown   TSRosWSetRecomputeJacobian - Set whether to recompute the Jacobian at each stage. The default is to update the Jacobian once per step.
1140e27a552bSJed Brown 
1141e27a552bSJed Brown   Logically collective
1142e27a552bSJed Brown 
1143e27a552bSJed Brown   Input Parameter:
1144e27a552bSJed Brown +  ts - timestepping context
114561692a83SJed Brown -  flg - PETSC_TRUE to recompute the Jacobian at each stage
1146e27a552bSJed Brown 
1147e27a552bSJed Brown   Level: intermediate
1148e27a552bSJed Brown 
1149e27a552bSJed Brown .seealso: TSRosWGetType()
1150e27a552bSJed Brown @*/
115161692a83SJed Brown PetscErrorCode TSRosWSetRecomputeJacobian(TS ts,PetscBool flg)
1152e27a552bSJed Brown {
1153e27a552bSJed Brown   PetscErrorCode ierr;
1154e27a552bSJed Brown 
1155e27a552bSJed Brown   PetscFunctionBegin;
1156e27a552bSJed Brown   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
115761692a83SJed Brown   ierr = PetscTryMethod(ts,"TSRosWSetRecomputeJacobian_C",(TS,PetscBool),(ts,flg));CHKERRQ(ierr);
1158e27a552bSJed Brown   PetscFunctionReturn(0);
1159e27a552bSJed Brown }
1160e27a552bSJed Brown 
1161e27a552bSJed Brown EXTERN_C_BEGIN
1162e27a552bSJed Brown #undef __FUNCT__
1163e27a552bSJed Brown #define __FUNCT__ "TSRosWGetType_RosW"
116461692a83SJed Brown PetscErrorCode  TSRosWGetType_RosW(TS ts,const TSRosWType *rostype)
1165e27a552bSJed Brown {
116661692a83SJed Brown   TS_RosW        *ros = (TS_RosW*)ts->data;
1167e27a552bSJed Brown   PetscErrorCode ierr;
1168e27a552bSJed Brown 
1169e27a552bSJed Brown   PetscFunctionBegin;
117061692a83SJed Brown   if (!ros->tableau) {ierr = TSRosWSetType(ts,TSRosWDefault);CHKERRQ(ierr);}
117161692a83SJed Brown   *rostype = ros->tableau->name;
1172e27a552bSJed Brown   PetscFunctionReturn(0);
1173e27a552bSJed Brown }
1174e27a552bSJed Brown #undef __FUNCT__
1175e27a552bSJed Brown #define __FUNCT__ "TSRosWSetType_RosW"
117661692a83SJed Brown PetscErrorCode  TSRosWSetType_RosW(TS ts,const TSRosWType rostype)
1177e27a552bSJed Brown {
117861692a83SJed Brown   TS_RosW         *ros = (TS_RosW*)ts->data;
1179e27a552bSJed Brown   PetscErrorCode  ierr;
1180e27a552bSJed Brown   PetscBool       match;
118161692a83SJed Brown   RosWTableauLink link;
1182e27a552bSJed Brown 
1183e27a552bSJed Brown   PetscFunctionBegin;
118461692a83SJed Brown   if (ros->tableau) {
118561692a83SJed Brown     ierr = PetscStrcmp(ros->tableau->name,rostype,&match);CHKERRQ(ierr);
1186e27a552bSJed Brown     if (match) PetscFunctionReturn(0);
1187e27a552bSJed Brown   }
118861692a83SJed Brown   for (link = RosWTableauList; link; link=link->next) {
118961692a83SJed Brown     ierr = PetscStrcmp(link->tab.name,rostype,&match);CHKERRQ(ierr);
1190e27a552bSJed Brown     if (match) {
1191e27a552bSJed Brown       ierr = TSReset_RosW(ts);CHKERRQ(ierr);
119261692a83SJed Brown       ros->tableau = &link->tab;
1193e27a552bSJed Brown       PetscFunctionReturn(0);
1194e27a552bSJed Brown     }
1195e27a552bSJed Brown   }
119661692a83SJed Brown   SETERRQ1(((PetscObject)ts)->comm,PETSC_ERR_ARG_UNKNOWN_TYPE,"Could not find '%s'",rostype);
1197e27a552bSJed Brown   PetscFunctionReturn(0);
1198e27a552bSJed Brown }
119961692a83SJed Brown 
1200e27a552bSJed Brown #undef __FUNCT__
120161692a83SJed Brown #define __FUNCT__ "TSRosWSetRecomputeJacobian_RosW"
120261692a83SJed Brown PetscErrorCode  TSRosWSetRecomputeJacobian_RosW(TS ts,PetscBool flg)
1203e27a552bSJed Brown {
120461692a83SJed Brown   TS_RosW *ros = (TS_RosW*)ts->data;
1205e27a552bSJed Brown 
1206e27a552bSJed Brown   PetscFunctionBegin;
120761692a83SJed Brown   ros->recompute_jacobian = flg;
1208e27a552bSJed Brown   PetscFunctionReturn(0);
1209e27a552bSJed Brown }
1210e27a552bSJed Brown EXTERN_C_END
1211e27a552bSJed Brown 
1212e27a552bSJed Brown /* ------------------------------------------------------------ */
1213e27a552bSJed Brown /*MC
1214020d8f30SJed Brown       TSROSW - ODE solver using Rosenbrock-W schemes
1215e27a552bSJed Brown 
1216e27a552bSJed Brown   These methods are intended for problems with well-separated time scales, especially when a slow scale is strongly
1217e27a552bSJed Brown   nonlinear such that it is expensive to solve with a fully implicit method. The user should provide the stiff part
1218e27a552bSJed Brown   of the equation using TSSetIFunction() and the non-stiff part with TSSetRHSFunction().
1219e27a552bSJed Brown 
1220e27a552bSJed Brown   Notes:
122161692a83SJed Brown   This method currently only works with autonomous ODE and DAE.
122261692a83SJed Brown 
122361692a83SJed Brown   Developer notes:
122461692a83SJed Brown   Rosenbrock-W methods are typically specified for autonomous ODE
122561692a83SJed Brown 
122661692a83SJed Brown $  xdot = f(x)
122761692a83SJed Brown 
122861692a83SJed Brown   by the stage equations
122961692a83SJed Brown 
123061692a83SJed Brown $  k_i = h f(x_0 + sum_j alpha_ij k_j) + h J sum_j gamma_ij k_j
123161692a83SJed Brown 
123261692a83SJed Brown   and step completion formula
123361692a83SJed Brown 
123461692a83SJed Brown $  x_1 = x_0 + sum_j b_j k_j
123561692a83SJed Brown 
123661692a83SJed Brown   with step size h and coefficients alpha_ij, gamma_ij, and b_i. Implementing the method in this form would require f(x)
123761692a83SJed Brown   and the Jacobian J to be available, in addition to the shifted matrix I - h gamma_ii J. Following Hairer and Wanner,
123861692a83SJed Brown   we define new variables for the stage equations
123961692a83SJed Brown 
124061692a83SJed Brown $  y_i = gamma_ij k_j
124161692a83SJed Brown 
124261692a83SJed Brown   The k_j can be recovered because Gamma is invertible. Let C be the lower triangular part of Gamma^{-1} and define
124361692a83SJed Brown 
124461692a83SJed Brown $  A = Alpha Gamma^{-1}, bt^T = b^T Gamma^{-i}
124561692a83SJed Brown 
124661692a83SJed Brown   to rewrite the method as
124761692a83SJed Brown 
124861692a83SJed Brown $  [M/(h gamma_ii) - J] y_i = f(x_0 + sum_j a_ij y_j) + M sum_j (c_ij/h) y_j
124961692a83SJed Brown $  x_1 = x_0 + sum_j bt_j y_j
125061692a83SJed Brown 
125161692a83SJed Brown    where we have introduced the mass matrix M. Continue by defining
125261692a83SJed Brown 
125361692a83SJed Brown $  ydot_i = 1/(h gamma_ii) y_i - sum_j (c_ij/h) y_j
125461692a83SJed Brown 
125561692a83SJed Brown    or, more compactly in tensor notation
125661692a83SJed Brown 
125761692a83SJed Brown $  Ydot = 1/h (Gamma^{-1} \otimes I) Y .
125861692a83SJed Brown 
125961692a83SJed Brown    Note that Gamma^{-1} is lower triangular. With this definition of Ydot in terms of known quantities and the current
126061692a83SJed Brown    stage y_i, the stage equations reduce to performing one Newton step (typically with a lagged Jacobian) on the
126161692a83SJed Brown    equation
126261692a83SJed Brown 
126361692a83SJed Brown $  g(x_0 + sum_j a_ij y_j + y_i, ydot_i) = 0
126461692a83SJed Brown 
126561692a83SJed Brown    with initial guess y_i = 0.
1266e27a552bSJed Brown 
1267e27a552bSJed Brown   Level: beginner
1268e27a552bSJed Brown 
1269020d8f30SJed Brown .seealso:  TSCreate(), TS, TSSetType(), TSRosWSetType(), TSRosWRegister()
1270e27a552bSJed Brown 
1271e27a552bSJed Brown M*/
1272e27a552bSJed Brown EXTERN_C_BEGIN
1273e27a552bSJed Brown #undef __FUNCT__
1274e27a552bSJed Brown #define __FUNCT__ "TSCreate_RosW"
1275e27a552bSJed Brown PetscErrorCode  TSCreate_RosW(TS ts)
1276e27a552bSJed Brown {
127761692a83SJed Brown   TS_RosW        *ros;
1278e27a552bSJed Brown   PetscErrorCode ierr;
1279e27a552bSJed Brown 
1280e27a552bSJed Brown   PetscFunctionBegin;
1281e27a552bSJed Brown #if !defined(PETSC_USE_DYNAMIC_LIBRARIES)
1282e27a552bSJed Brown   ierr = TSRosWInitializePackage(PETSC_NULL);CHKERRQ(ierr);
1283e27a552bSJed Brown #endif
1284e27a552bSJed Brown 
1285e27a552bSJed Brown   ts->ops->reset          = TSReset_RosW;
1286e27a552bSJed Brown   ts->ops->destroy        = TSDestroy_RosW;
1287e27a552bSJed Brown   ts->ops->view           = TSView_RosW;
1288e27a552bSJed Brown   ts->ops->setup          = TSSetUp_RosW;
1289e27a552bSJed Brown   ts->ops->step           = TSStep_RosW;
1290e27a552bSJed Brown   ts->ops->interpolate    = TSInterpolate_RosW;
12911c3436cfSJed Brown   ts->ops->evaluatestep   = TSEvaluateStep_RosW;
1292e27a552bSJed Brown   ts->ops->setfromoptions = TSSetFromOptions_RosW;
1293e27a552bSJed Brown   ts->ops->snesfunction   = SNESTSFormFunction_RosW;
1294e27a552bSJed Brown   ts->ops->snesjacobian   = SNESTSFormJacobian_RosW;
1295e27a552bSJed Brown 
129661692a83SJed Brown   ierr = PetscNewLog(ts,TS_RosW,&ros);CHKERRQ(ierr);
129761692a83SJed Brown   ts->data = (void*)ros;
1298e27a552bSJed Brown 
1299e27a552bSJed Brown   ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSRosWGetType_C","TSRosWGetType_RosW",TSRosWGetType_RosW);CHKERRQ(ierr);
1300e27a552bSJed Brown   ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSRosWSetType_C","TSRosWSetType_RosW",TSRosWSetType_RosW);CHKERRQ(ierr);
130161692a83SJed Brown   ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSRosWSetRecomputeJacobian_C","TSRosWSetRecomputeJacobian_RosW",TSRosWSetRecomputeJacobian_RosW);CHKERRQ(ierr);
1302e27a552bSJed Brown   PetscFunctionReturn(0);
1303e27a552bSJed Brown }
1304e27a552bSJed Brown EXTERN_C_END
1305