xref: /petsc/src/ts/impls/rosw/rosw.c (revision b8123dae7f872ca50579e8005f6d2cd0e4534f13)
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 */
13b45d2f2cSJed Brown #include <petsc-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
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 
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,
2381f80e275SEmil Constantinescu       b = 1,
2391f80e275SEmil Constantinescu       binterpt=1;
2401f80e275SEmil Constantinescu 
2411f80e275SEmil 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,
2481f80e275SEmil Constantinescu       b = 1,
2491f80e275SEmil Constantinescu       binterpt=1;
2501f80e275SEmil 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};
2601f80e275SEmil Constantinescu       PetscReal  binterpt[2][2];
2611f80e275SEmil Constantinescu       binterpt[0][0]=g-1.0;
2621f80e275SEmil Constantinescu       binterpt[1][0]=2.0-g;
2631f80e275SEmil Constantinescu       binterpt[0][1]=g-1.5;
2641f80e275SEmil Constantinescu       binterpt[1][1]=1.5-g;
2651f80e275SEmil 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};
2741f80e275SEmil Constantinescu       PetscReal  binterpt[2][2];
2751f80e275SEmil Constantinescu       binterpt[0][0]=g-1.0;
2761f80e275SEmil Constantinescu       binterpt[1][0]=2.0-g;
2771f80e275SEmil Constantinescu       binterpt[0][1]=g-1.5;
2781f80e275SEmil Constantinescu       binterpt[1][1]=1.5-g;
2791f80e275SEmil 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;
2831f80e275SEmil 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};
2931f80e275SEmil Constantinescu 
2941f80e275SEmil Constantinescu       binterpt[0][0]=-0.8094010767585034;
2951f80e275SEmil Constantinescu       binterpt[1][0]=-0.5;
2961f80e275SEmil Constantinescu       binterpt[2][0]=2.3094010767585034;
2971f80e275SEmil Constantinescu       binterpt[0][1]=0.9641016151377548;
2981f80e275SEmil Constantinescu       binterpt[1][1]=0.5;
2991f80e275SEmil Constantinescu       binterpt[2][1]=-1.4641016151377548;
3001f80e275SEmil 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};
3581f80e275SEmil Constantinescu 
3591f80e275SEmil Constantinescu       PetscReal  binterpt[3][2];
3601f80e275SEmil Constantinescu       binterpt[0][0]=3.793692883777660870425141387941;
3611f80e275SEmil Constantinescu       binterpt[1][0]=-2.918692883777660870425141387941;
3621f80e275SEmil Constantinescu       binterpt[2][0]=0.125;
3631f80e275SEmil Constantinescu       binterpt[0][1]=-0.725741064379812106687651020584;
3641f80e275SEmil Constantinescu       binterpt[1][1]=0.559074397713145440020984353917;
3651f80e275SEmil Constantinescu       binterpt[2][1]=0.16666666666666666666666666666667;
3661f80e275SEmil Constantinescu 
3671f80e275SEmil 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.};
380c0cb691aSEmil Constantinescu 
381c0cb691aSEmil Constantinescu         PetscReal  binterpt[3][2];
382c0cb691aSEmil Constantinescu         binterpt[0][0]=0.089316397477040902157517886164709;
383c0cb691aSEmil Constantinescu         binterpt[1][0]=-0.91068360252295909784248211383529;
384c0cb691aSEmil Constantinescu         binterpt[2][0]=1.8213672050459181956849642276706;
385c0cb691aSEmil Constantinescu         binterpt[0][1]=0.077350269189625764509148780501957;
386c0cb691aSEmil Constantinescu         binterpt[1][1]=1.077350269189625764509148780502;
387c0cb691aSEmil Constantinescu         binterpt[2][1]=-1.1547005383792515290182975610039;
388c0cb691aSEmil Constantinescu     ierr = TSRosWRegister(TSROSWASSP3P3S1C,3,3,&A[0][0],&Gamma[0][0],b,b2,2,&binterpt[0][0]);CHKERRQ(ierr);
389b1c69cc3SEmil Constantinescu   }
390b1c69cc3SEmil Constantinescu 
391b1c69cc3SEmil Constantinescu   {
392b1c69cc3SEmil Constantinescu     const PetscReal
393b1c69cc3SEmil Constantinescu       A[4][4] = {{0,0,0,0},
394b1c69cc3SEmil Constantinescu                  {1./2.,0,0,0},
395b1c69cc3SEmil Constantinescu                  {1./2.,1./2.,0,0},
396b1c69cc3SEmil Constantinescu                  {1./6.,1./6.,1./6.,0}},
397b1c69cc3SEmil Constantinescu       Gamma[4][4] = {{1./2.,0,0,0},
398b1c69cc3SEmil Constantinescu                      {0.0,1./4.,0,0},
399b1c69cc3SEmil Constantinescu                      {-2.,-2./3.,2./3.,0},
400b1c69cc3SEmil Constantinescu                      {1./2.,5./36.,-2./9,0}},
401b1c69cc3SEmil Constantinescu         b[4] = {1./6.,1./6.,1./6.,1./2.},
402b1c69cc3SEmil Constantinescu         b2[4] = {1./8.,3./4.,1./8.,0};
403c0cb691aSEmil Constantinescu         PetscReal  binterpt[4][3];
404c0cb691aSEmil Constantinescu         binterpt[0][0]=6.25;
405c0cb691aSEmil Constantinescu         binterpt[1][0]=-30.25;
406c0cb691aSEmil Constantinescu         binterpt[2][0]=1.75;
407c0cb691aSEmil Constantinescu         binterpt[3][0]=23.25;
408c0cb691aSEmil Constantinescu         binterpt[0][1]=-9.75;
409c0cb691aSEmil Constantinescu         binterpt[1][1]=58.75;
410c0cb691aSEmil Constantinescu         binterpt[2][1]=-3.25;
411c0cb691aSEmil Constantinescu         binterpt[3][1]=-45.75;
412c0cb691aSEmil Constantinescu         binterpt[0][2]=3.6666666666666666666666666666667;
413c0cb691aSEmil Constantinescu         binterpt[1][2]=-28.333333333333333333333333333333;
414c0cb691aSEmil Constantinescu         binterpt[2][2]=1.6666666666666666666666666666667;
415c0cb691aSEmil Constantinescu         binterpt[3][2]=23.;
416c0cb691aSEmil Constantinescu         ierr = TSRosWRegister(TSROSWLASSP3P4S2C,3,4,&A[0][0],&Gamma[0][0],b,b2,3,&binterpt[0][0]);CHKERRQ(ierr);
417b1c69cc3SEmil Constantinescu   }
418b1c69cc3SEmil Constantinescu 
419b1c69cc3SEmil Constantinescu   {
420b1c69cc3SEmil Constantinescu     const PetscReal
421b1c69cc3SEmil Constantinescu       A[4][4] = {{0,0,0,0},
422b1c69cc3SEmil Constantinescu                  {1./2.,0,0,0},
423b1c69cc3SEmil Constantinescu                  {1./2.,1./2.,0,0},
424b1c69cc3SEmil Constantinescu                  {1./6.,1./6.,1./6.,0}},
425b1c69cc3SEmil Constantinescu       Gamma[4][4] = {{1./2.,0,0,0},
426b1c69cc3SEmil Constantinescu                      {0.0,3./4.,0,0},
427b1c69cc3SEmil Constantinescu                      {-2./3.,-23./9.,2./9.,0},
428b1c69cc3SEmil Constantinescu                      {1./18.,65./108.,-2./27,0}},
429b1c69cc3SEmil Constantinescu         b[4] = {1./6.,1./6.,1./6.,1./2.},
430b1c69cc3SEmil Constantinescu         b2[4] = {3./16.,10./16.,3./16.,0};
431c0cb691aSEmil Constantinescu 
432c0cb691aSEmil Constantinescu         PetscReal  binterpt[4][3];
433c0cb691aSEmil Constantinescu         binterpt[0][0]=1.6911764705882352941176470588235;
434c0cb691aSEmil Constantinescu         binterpt[1][0]=3.6813725490196078431372549019608;
435c0cb691aSEmil Constantinescu         binterpt[2][0]=0.23039215686274509803921568627451;
436c0cb691aSEmil Constantinescu         binterpt[3][0]=-4.6029411764705882352941176470588;
437c0cb691aSEmil Constantinescu         binterpt[0][1]=-0.95588235294117647058823529411765;
438c0cb691aSEmil Constantinescu         binterpt[1][1]=-6.2401960784313725490196078431373;
439c0cb691aSEmil Constantinescu         binterpt[2][1]=-0.31862745098039215686274509803922;
440c0cb691aSEmil Constantinescu         binterpt[3][1]=7.5147058823529411764705882352941;
441c0cb691aSEmil Constantinescu         binterpt[0][2]=-0.56862745098039215686274509803922;
442c0cb691aSEmil Constantinescu         binterpt[1][2]=2.7254901960784313725490196078431;
443c0cb691aSEmil Constantinescu         binterpt[2][2]=0.25490196078431372549019607843137;
444c0cb691aSEmil Constantinescu         binterpt[3][2]=-2.4117647058823529411764705882353;
445c0cb691aSEmil Constantinescu         ierr = TSRosWRegister(TSROSWLLSSP3P4S2C,3,4,&A[0][0],&Gamma[0][0],b,b2,3,&binterpt[0][0]);CHKERRQ(ierr);
446b1c69cc3SEmil Constantinescu   }
447753f8adbSEmil Constantinescu 
448753f8adbSEmil Constantinescu  {
449753f8adbSEmil Constantinescu    PetscReal A[4][4],Gamma[4][4],b[4],b2[4];
4503ca35412SEmil Constantinescu    PetscReal  binterpt[4][3];
451753f8adbSEmil Constantinescu 
452753f8adbSEmil Constantinescu    Gamma[0][0]=0.4358665215084589994160194475295062513822671686978816;
45305e8e825SJed Brown    Gamma[0][1]=0; Gamma[0][2]=0; Gamma[0][3]=0;
454753f8adbSEmil Constantinescu    Gamma[1][0]=-1.997527830934941248426324674704153457289527280554476;
455753f8adbSEmil Constantinescu    Gamma[1][1]=0.4358665215084589994160194475295062513822671686978816;
45605e8e825SJed Brown    Gamma[1][2]=0; Gamma[1][3]=0;
457753f8adbSEmil Constantinescu    Gamma[2][0]=-1.007948511795029620852002345345404191008352770119903;
458753f8adbSEmil Constantinescu    Gamma[2][1]=-0.004648958462629345562774289390054679806993396798458131;
459753f8adbSEmil Constantinescu    Gamma[2][2]=0.4358665215084589994160194475295062513822671686978816;
46005e8e825SJed Brown    Gamma[2][3]=0;
461753f8adbSEmil Constantinescu    Gamma[3][0]=-0.6685429734233467180451604600279552604364311322650783;
462753f8adbSEmil Constantinescu    Gamma[3][1]=0.6056625986449338476089525334450053439525178740492984;
463753f8adbSEmil Constantinescu    Gamma[3][2]=-0.9717899277217721234705114616271378792182450260943198;
464753f8adbSEmil Constantinescu    Gamma[3][3]=0;
465753f8adbSEmil Constantinescu 
46605e8e825SJed Brown    A[0][0]=0; A[0][1]=0; A[0][2]=0; A[0][3]=0;
467753f8adbSEmil Constantinescu    A[1][0]=0.8717330430169179988320388950590125027645343373957631;
46805e8e825SJed Brown    A[1][1]=0; A[1][2]=0; A[1][3]=0;
469753f8adbSEmil Constantinescu    A[2][0]=0.5275890119763004115618079766722914408876108660811028;
470753f8adbSEmil Constantinescu    A[2][1]=0.07241098802369958843819203208518599088698057726988732;
47105e8e825SJed Brown    A[2][2]=0; A[2][3]=0;
472753f8adbSEmil Constantinescu    A[3][0]=0.3990960076760701320627260685975778145384666450351314;
473753f8adbSEmil Constantinescu    A[3][1]=-0.4375576546135194437228463747348862825846903771419953;
474753f8adbSEmil Constantinescu    A[3][2]=1.038461646937449311660120300601880176655352737312713;
47505e8e825SJed Brown    A[3][3]=0;
476753f8adbSEmil Constantinescu 
477753f8adbSEmil Constantinescu    b[0]=0.1876410243467238251612921333138006734899663569186926;
478753f8adbSEmil Constantinescu    b[1]=-0.5952974735769549480478230473706443582188442040780541;
479753f8adbSEmil Constantinescu    b[2]=0.9717899277217721234705114616271378792182450260943198;
480753f8adbSEmil Constantinescu    b[3]=0.4358665215084589994160194475295062513822671686978816;
481753f8adbSEmil Constantinescu 
482753f8adbSEmil Constantinescu    b2[0]=0.2147402862233891404862383521089097657790734483804460;
483753f8adbSEmil Constantinescu    b2[1]=-0.4851622638849390928209050538171743017757490232519684;
484753f8adbSEmil Constantinescu    b2[2]=0.8687250025203875511662123688667549217531982787600080;
485753f8adbSEmil Constantinescu    b2[3]=0.4016969751411624011684543450940068201770721128357014;
486753f8adbSEmil Constantinescu 
4873ca35412SEmil Constantinescu    binterpt[0][0]=2.2565812720167954547104627844105;
4883ca35412SEmil Constantinescu    binterpt[1][0]=1.349166413351089573796243820819;
4893ca35412SEmil Constantinescu    binterpt[2][0]=-2.4695174540533503758652847586647;
4903ca35412SEmil Constantinescu    binterpt[3][0]=-0.13623023131453465264142184656474;
4913ca35412SEmil Constantinescu    binterpt[0][1]=-3.0826699111559187902922463354557;
4923ca35412SEmil Constantinescu    binterpt[1][1]=-2.4689115685996042534544925650515;
4933ca35412SEmil Constantinescu    binterpt[2][1]=5.7428279814696677152129332773553;
4943ca35412SEmil Constantinescu    binterpt[3][1]=-0.19124650171414467146619437684812;
4953ca35412SEmil Constantinescu    binterpt[0][2]=1.0137296634858471607430756831148;
4963ca35412SEmil Constantinescu    binterpt[1][2]=0.52444768167155973161042570784064;
4973ca35412SEmil Constantinescu    binterpt[2][2]=-2.3015205996945452158771370439586;
4983ca35412SEmil Constantinescu    binterpt[3][2]=0.76334325453713832352363565300308;
499f4aed992SEmil Constantinescu 
500f73f8d2cSSatish Balay    ierr = TSRosWRegister(TSROSWARK3,3,4,&A[0][0],&Gamma[0][0],b,b2,3,&binterpt[0][0]);CHKERRQ(ierr);
501753f8adbSEmil Constantinescu   }
502753f8adbSEmil Constantinescu 
503e27a552bSJed Brown   PetscFunctionReturn(0);
504e27a552bSJed Brown }
505e27a552bSJed Brown 
506e27a552bSJed Brown #undef __FUNCT__
507e27a552bSJed Brown #define __FUNCT__ "TSRosWRegisterDestroy"
508e27a552bSJed Brown /*@C
509e27a552bSJed Brown    TSRosWRegisterDestroy - Frees the list of schemes that were registered by TSRosWRegister().
510e27a552bSJed Brown 
511e27a552bSJed Brown    Not Collective
512e27a552bSJed Brown 
513e27a552bSJed Brown    Level: advanced
514e27a552bSJed Brown 
515e27a552bSJed Brown .keywords: TSRosW, register, destroy
516e27a552bSJed Brown .seealso: TSRosWRegister(), TSRosWRegisterAll(), TSRosWRegisterDynamic()
517e27a552bSJed Brown @*/
518e27a552bSJed Brown PetscErrorCode TSRosWRegisterDestroy(void)
519e27a552bSJed Brown {
520e27a552bSJed Brown   PetscErrorCode ierr;
52161692a83SJed Brown   RosWTableauLink link;
522e27a552bSJed Brown 
523e27a552bSJed Brown   PetscFunctionBegin;
52461692a83SJed Brown   while ((link = RosWTableauList)) {
52561692a83SJed Brown     RosWTableau t = &link->tab;
52661692a83SJed Brown     RosWTableauList = link->next;
52761692a83SJed Brown     ierr = PetscFree5(t->A,t->Gamma,t->b,t->ASum,t->GammaSum);CHKERRQ(ierr);
52843b21953SEmil Constantinescu     ierr = PetscFree5(t->At,t->bt,t->GammaInv,t->GammaZeroDiag,t->GammaExplicitCorr);CHKERRQ(ierr);
529fe7e6d57SJed Brown     ierr = PetscFree2(t->bembed,t->bembedt);CHKERRQ(ierr);
530f4aed992SEmil Constantinescu     ierr = PetscFree(t->binterpt);CHKERRQ(ierr);
531e27a552bSJed Brown     ierr = PetscFree(t->name);CHKERRQ(ierr);
532e27a552bSJed Brown     ierr = PetscFree(link);CHKERRQ(ierr);
533e27a552bSJed Brown   }
534e27a552bSJed Brown   TSRosWRegisterAllCalled = PETSC_FALSE;
535e27a552bSJed Brown   PetscFunctionReturn(0);
536e27a552bSJed Brown }
537e27a552bSJed Brown 
538e27a552bSJed Brown #undef __FUNCT__
539e27a552bSJed Brown #define __FUNCT__ "TSRosWInitializePackage"
540e27a552bSJed Brown /*@C
541e27a552bSJed Brown   TSRosWInitializePackage - This function initializes everything in the TSRosW package. It is called
542e27a552bSJed Brown   from PetscDLLibraryRegister() when using dynamic libraries, and on the first call to TSCreate_RosW()
543e27a552bSJed Brown   when using static libraries.
544e27a552bSJed Brown 
545e27a552bSJed Brown   Input Parameter:
546e27a552bSJed Brown   path - The dynamic library path, or PETSC_NULL
547e27a552bSJed Brown 
548e27a552bSJed Brown   Level: developer
549e27a552bSJed Brown 
550e27a552bSJed Brown .keywords: TS, TSRosW, initialize, package
551e27a552bSJed Brown .seealso: PetscInitialize()
552e27a552bSJed Brown @*/
553e27a552bSJed Brown PetscErrorCode TSRosWInitializePackage(const char path[])
554e27a552bSJed Brown {
555e27a552bSJed Brown   PetscErrorCode ierr;
556e27a552bSJed Brown 
557e27a552bSJed Brown   PetscFunctionBegin;
558e27a552bSJed Brown   if (TSRosWPackageInitialized) PetscFunctionReturn(0);
559e27a552bSJed Brown   TSRosWPackageInitialized = PETSC_TRUE;
560e27a552bSJed Brown   ierr = TSRosWRegisterAll();CHKERRQ(ierr);
561e27a552bSJed Brown   ierr = PetscRegisterFinalize(TSRosWFinalizePackage);CHKERRQ(ierr);
562e27a552bSJed Brown   PetscFunctionReturn(0);
563e27a552bSJed Brown }
564e27a552bSJed Brown 
565e27a552bSJed Brown #undef __FUNCT__
566e27a552bSJed Brown #define __FUNCT__ "TSRosWFinalizePackage"
567e27a552bSJed Brown /*@C
568e27a552bSJed Brown   TSRosWFinalizePackage - This function destroys everything in the TSRosW package. It is
569e27a552bSJed Brown   called from PetscFinalize().
570e27a552bSJed Brown 
571e27a552bSJed Brown   Level: developer
572e27a552bSJed Brown 
573e27a552bSJed Brown .keywords: Petsc, destroy, package
574e27a552bSJed Brown .seealso: PetscFinalize()
575e27a552bSJed Brown @*/
576e27a552bSJed Brown PetscErrorCode TSRosWFinalizePackage(void)
577e27a552bSJed Brown {
578e27a552bSJed Brown   PetscErrorCode ierr;
579e27a552bSJed Brown 
580e27a552bSJed Brown   PetscFunctionBegin;
581e27a552bSJed Brown   TSRosWPackageInitialized = PETSC_FALSE;
582e27a552bSJed Brown   ierr = TSRosWRegisterDestroy();CHKERRQ(ierr);
583e27a552bSJed Brown   PetscFunctionReturn(0);
584e27a552bSJed Brown }
585e27a552bSJed Brown 
586e27a552bSJed Brown #undef __FUNCT__
587e27a552bSJed Brown #define __FUNCT__ "TSRosWRegister"
588e27a552bSJed Brown /*@C
58961692a83SJed Brown    TSRosWRegister - register a Rosenbrock W scheme by providing the entries in the Butcher tableau and optionally embedded approximations and interpolation
590e27a552bSJed Brown 
591e27a552bSJed Brown    Not Collective, but the same schemes should be registered on all processes on which they will be used
592e27a552bSJed Brown 
593e27a552bSJed Brown    Input Parameters:
594e27a552bSJed Brown +  name - identifier for method
595e27a552bSJed Brown .  order - approximation order of method
596e27a552bSJed Brown .  s - number of stages, this is the dimension of the matrices below
59761692a83SJed Brown .  A - Table of propagated stage coefficients (dimension s*s, row-major), strictly lower triangular
59861692a83SJed Brown .  Gamma - Table of coefficients in implicit stage equations (dimension s*s, row-major), lower triangular with nonzero diagonal
599fe7e6d57SJed Brown .  b - Step completion table (dimension s)
600fe7e6d57SJed Brown -  bembed - Step completion table for a scheme of order one less (dimension s, PETSC_NULL if no embedded scheme is available)
601f4aed992SEmil Constantinescu .  pinterp - Order of the interpolation scheme, equal to the number of columns of binterpt
602f4aed992SEmil Constantinescu .  binterpt - Coefficients of the interpolation formula (dimension s*pinterp)
603e27a552bSJed Brown 
604e27a552bSJed Brown    Notes:
60561692a83SJed Brown    Several Rosenbrock W methods are provided, this function is only needed to create new methods.
606e27a552bSJed Brown 
607e27a552bSJed Brown    Level: advanced
608e27a552bSJed Brown 
609e27a552bSJed Brown .keywords: TS, register
610e27a552bSJed Brown 
611e27a552bSJed Brown .seealso: TSRosW
612e27a552bSJed Brown @*/
613e27a552bSJed Brown PetscErrorCode TSRosWRegister(const TSRosWType name,PetscInt order,PetscInt s,
614f4aed992SEmil Constantinescu                               const PetscReal A[],const PetscReal Gamma[],const PetscReal b[],const PetscReal bembed[],
615f4aed992SEmil Constantinescu                                  PetscInt pinterp,const PetscReal binterpt[])
616e27a552bSJed Brown {
617e27a552bSJed Brown   PetscErrorCode ierr;
61861692a83SJed Brown   RosWTableauLink link;
61961692a83SJed Brown   RosWTableau t;
62061692a83SJed Brown   PetscInt i,j,k;
62161692a83SJed Brown   PetscScalar *GammaInv;
622e27a552bSJed Brown 
623e27a552bSJed Brown   PetscFunctionBegin;
624fe7e6d57SJed Brown   PetscValidCharPointer(name,1);
625fe7e6d57SJed Brown   PetscValidPointer(A,4);
626fe7e6d57SJed Brown   PetscValidPointer(Gamma,5);
627fe7e6d57SJed Brown   PetscValidPointer(b,6);
628fe7e6d57SJed Brown   if (bembed) PetscValidPointer(bembed,7);
629fe7e6d57SJed Brown 
630e27a552bSJed Brown   ierr = PetscMalloc(sizeof(*link),&link);CHKERRQ(ierr);
631e27a552bSJed Brown   ierr = PetscMemzero(link,sizeof(*link));CHKERRQ(ierr);
632e27a552bSJed Brown   t = &link->tab;
633e27a552bSJed Brown   ierr = PetscStrallocpy(name,&t->name);CHKERRQ(ierr);
634e27a552bSJed Brown   t->order = order;
635e27a552bSJed Brown   t->s = s;
63661692a83SJed 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);
63743b21953SEmil 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);
638e27a552bSJed Brown   ierr = PetscMemcpy(t->A,A,s*s*sizeof(A[0]));CHKERRQ(ierr);
63961692a83SJed Brown   ierr = PetscMemcpy(t->Gamma,Gamma,s*s*sizeof(Gamma[0]));CHKERRQ(ierr);
64043b21953SEmil Constantinescu   ierr = PetscMemcpy(t->GammaExplicitCorr,Gamma,s*s*sizeof(Gamma[0]));CHKERRQ(ierr);
64161692a83SJed Brown   ierr = PetscMemcpy(t->b,b,s*sizeof(b[0]));CHKERRQ(ierr);
642fe7e6d57SJed Brown   if (bembed) {
643fe7e6d57SJed Brown     ierr = PetscMalloc2(s,PetscReal,&t->bembed,s,PetscReal,&t->bembedt);CHKERRQ(ierr);
644fe7e6d57SJed Brown     ierr = PetscMemcpy(t->bembed,bembed,s*sizeof(bembed[0]));CHKERRQ(ierr);
645fe7e6d57SJed Brown   }
64661692a83SJed Brown   for (i=0; i<s; i++) {
64761692a83SJed Brown     t->ASum[i] = 0;
64861692a83SJed Brown     t->GammaSum[i] = 0;
64961692a83SJed Brown     for (j=0; j<s; j++) {
65061692a83SJed Brown       t->ASum[i] += A[i*s+j];
651fe7e6d57SJed Brown       t->GammaSum[i] += Gamma[i*s+j];
65261692a83SJed Brown     }
65361692a83SJed Brown   }
65461692a83SJed Brown   ierr = PetscMalloc(s*s*sizeof(PetscScalar),&GammaInv);CHKERRQ(ierr); /* Need to use Scalar for inverse, then convert back to Real */
65561692a83SJed Brown   for (i=0; i<s*s; i++) GammaInv[i] = Gamma[i];
656fd96d5b0SEmil Constantinescu   for (i=0; i<s; i++) {
657fd96d5b0SEmil Constantinescu     if (Gamma[i*s+i] == 0.0) {
658fd96d5b0SEmil Constantinescu       GammaInv[i*s+i] = 1.0;
659c17803e7SJed Brown       t->GammaZeroDiag[i] = PETSC_TRUE;
660fd96d5b0SEmil Constantinescu     } else {
661c17803e7SJed Brown       t->GammaZeroDiag[i] = PETSC_FALSE;
662fd96d5b0SEmil Constantinescu     }
663fd96d5b0SEmil Constantinescu   }
664fd96d5b0SEmil Constantinescu 
66561692a83SJed Brown   switch (s) {
66661692a83SJed Brown   case 1: GammaInv[0] = 1./GammaInv[0]; break;
66796b95a6bSBarry Smith   case 2: ierr = PetscKernel_A_gets_inverse_A_2(GammaInv,0);CHKERRQ(ierr); break;
66896b95a6bSBarry Smith   case 3: ierr = PetscKernel_A_gets_inverse_A_3(GammaInv,0);CHKERRQ(ierr); break;
66996b95a6bSBarry Smith   case 4: ierr = PetscKernel_A_gets_inverse_A_4(GammaInv,0);CHKERRQ(ierr); break;
67061692a83SJed Brown   case 5: {
67161692a83SJed Brown     PetscInt ipvt5[5];
67261692a83SJed Brown     MatScalar work5[5*5];
67396b95a6bSBarry Smith     ierr = PetscKernel_A_gets_inverse_A_5(GammaInv,ipvt5,work5,0);CHKERRQ(ierr); break;
67461692a83SJed Brown   }
67596b95a6bSBarry Smith   case 6: ierr = PetscKernel_A_gets_inverse_A_6(GammaInv,0);CHKERRQ(ierr); break;
67696b95a6bSBarry Smith   case 7: ierr = PetscKernel_A_gets_inverse_A_7(GammaInv,0);CHKERRQ(ierr); break;
67761692a83SJed Brown   default: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented for %D stages",s);
67861692a83SJed Brown   }
67961692a83SJed Brown   for (i=0; i<s*s; i++) t->GammaInv[i] = PetscRealPart(GammaInv[i]);
68061692a83SJed Brown   ierr = PetscFree(GammaInv);CHKERRQ(ierr);
68143b21953SEmil Constantinescu 
68243b21953SEmil Constantinescu   for (i=0; i<s; i++) {
68343b21953SEmil Constantinescu     for (k=0; k<i+1; k++) {
68443b21953SEmil Constantinescu       t->GammaExplicitCorr[i*s+k]=(t->GammaExplicitCorr[i*s+k])*(t->GammaInv[k*s+k]);
68543b21953SEmil Constantinescu       for (j=k+1; j<i+1; j++) {
68643b21953SEmil Constantinescu         t->GammaExplicitCorr[i*s+k]+=(t->GammaExplicitCorr[i*s+j])*(t->GammaInv[j*s+k]);
68743b21953SEmil Constantinescu       }
68843b21953SEmil Constantinescu     }
68943b21953SEmil Constantinescu   }
69043b21953SEmil Constantinescu 
69161692a83SJed Brown   for (i=0; i<s; i++) {
69261692a83SJed Brown     for (j=0; j<s; j++) {
69361692a83SJed Brown       t->At[i*s+j] = 0;
69461692a83SJed Brown       for (k=0; k<s; k++) {
69561692a83SJed Brown         t->At[i*s+j] += t->A[i*s+k] * t->GammaInv[k*s+j];
69661692a83SJed Brown       }
69761692a83SJed Brown     }
69861692a83SJed Brown     t->bt[i] = 0;
69961692a83SJed Brown     for (j=0; j<s; j++) {
70061692a83SJed Brown       t->bt[i] += t->b[j] * t->GammaInv[j*s+i];
70161692a83SJed Brown     }
702fe7e6d57SJed Brown     if (bembed) {
703fe7e6d57SJed Brown       t->bembedt[i] = 0;
704fe7e6d57SJed Brown       for (j=0; j<s; j++) {
705fe7e6d57SJed Brown         t->bembedt[i] += t->bembed[j] * t->GammaInv[j*s+i];
706fe7e6d57SJed Brown       }
707fe7e6d57SJed Brown     }
70861692a83SJed Brown   }
7098d59e960SJed Brown   t->ccfl = 1.0;                /* Fix this */
7108d59e960SJed Brown 
711f4aed992SEmil Constantinescu   t->pinterp = pinterp;
7123ca35412SEmil Constantinescu   ierr = PetscMalloc(s*pinterp*sizeof(binterpt[0]),&t->binterpt);CHKERRQ(ierr);
7133ca35412SEmil Constantinescu   ierr = PetscMemcpy(t->binterpt,binterpt,s*pinterp*sizeof(binterpt[0]));CHKERRQ(ierr);
71461692a83SJed Brown   link->next = RosWTableauList;
71561692a83SJed Brown   RosWTableauList = link;
716e27a552bSJed Brown   PetscFunctionReturn(0);
717e27a552bSJed Brown }
718e27a552bSJed Brown 
719e27a552bSJed Brown #undef __FUNCT__
7201c3436cfSJed Brown #define __FUNCT__ "TSEvaluateStep_RosW"
7211c3436cfSJed Brown /*
7221c3436cfSJed Brown  The step completion formula is
7231c3436cfSJed Brown 
7241c3436cfSJed Brown  x1 = x0 + b^T Y
7251c3436cfSJed Brown 
7261c3436cfSJed Brown  where Y is the multi-vector of stages corrections. This function can be called before or after ts->vec_sol has been
7271c3436cfSJed Brown  updated. Suppose we have a completion formula b and an embedded formula be of different order. We can write
7281c3436cfSJed Brown 
7291c3436cfSJed Brown  x1e = x0 + be^T Y
7301c3436cfSJed Brown      = x1 - b^T Y + be^T Y
7311c3436cfSJed Brown      = x1 + (be - b)^T Y
7321c3436cfSJed Brown 
7331c3436cfSJed Brown  so we can evaluate the method of different order even after the step has been optimistically completed.
7341c3436cfSJed Brown */
7351c3436cfSJed Brown static PetscErrorCode TSEvaluateStep_RosW(TS ts,PetscInt order,Vec X,PetscBool *done)
7361c3436cfSJed Brown {
7371c3436cfSJed Brown   TS_RosW        *ros = (TS_RosW*)ts->data;
7381c3436cfSJed Brown   RosWTableau    tab  = ros->tableau;
7391c3436cfSJed Brown   PetscScalar    *w = ros->work;
7401c3436cfSJed Brown   PetscInt       i;
7411c3436cfSJed Brown   PetscErrorCode ierr;
7421c3436cfSJed Brown 
7431c3436cfSJed Brown   PetscFunctionBegin;
7441c3436cfSJed Brown   if (order == tab->order) {
745108c343cSJed Brown     if (ros->status == TS_STEP_INCOMPLETE) { /* Use standard completion formula */
7461c3436cfSJed Brown       ierr = VecCopy(ts->vec_sol,X);CHKERRQ(ierr);
747de19f811SJed Brown       for (i=0; i<tab->s; i++) w[i] = tab->bt[i];
748de19f811SJed Brown       ierr = VecMAXPY(X,tab->s,w,ros->Y);CHKERRQ(ierr);
749108c343cSJed Brown     } else {ierr = VecCopy(ts->vec_sol,X);CHKERRQ(ierr);}
7501c3436cfSJed Brown     if (done) *done = PETSC_TRUE;
7511c3436cfSJed Brown     PetscFunctionReturn(0);
7521c3436cfSJed Brown   } else if (order == tab->order-1) {
7531c3436cfSJed Brown     if (!tab->bembedt) goto unavailable;
754108c343cSJed Brown     if (ros->status == TS_STEP_INCOMPLETE) { /* Use embedded completion formula */
7551c3436cfSJed Brown       ierr = VecCopy(ts->vec_sol,X);CHKERRQ(ierr);
756de19f811SJed Brown       for (i=0; i<tab->s; i++) w[i] = tab->bembedt[i];
757de19f811SJed Brown       ierr = VecMAXPY(X,tab->s,w,ros->Y);CHKERRQ(ierr);
758108c343cSJed Brown     } else {                    /* Use rollback-and-recomplete formula (bembedt - bt) */
759108c343cSJed Brown       for (i=0; i<tab->s; i++) w[i] = tab->bembedt[i] - tab->bt[i];
760108c343cSJed Brown       ierr = VecCopy(ts->vec_sol,X);CHKERRQ(ierr);
761108c343cSJed Brown       ierr = VecMAXPY(X,tab->s,w,ros->Y);CHKERRQ(ierr);
7621c3436cfSJed Brown     }
7631c3436cfSJed Brown     if (done) *done = PETSC_TRUE;
7641c3436cfSJed Brown     PetscFunctionReturn(0);
7651c3436cfSJed Brown   }
7661c3436cfSJed Brown   unavailable:
7671c3436cfSJed Brown   if (done) *done = PETSC_FALSE;
7681c3436cfSJed 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);
7691c3436cfSJed Brown   PetscFunctionReturn(0);
7701c3436cfSJed Brown }
7711c3436cfSJed Brown 
7721c3436cfSJed Brown #undef __FUNCT__
773e27a552bSJed Brown #define __FUNCT__ "TSStep_RosW"
774e27a552bSJed Brown static PetscErrorCode TSStep_RosW(TS ts)
775e27a552bSJed Brown {
77661692a83SJed Brown   TS_RosW         *ros = (TS_RosW*)ts->data;
77761692a83SJed Brown   RosWTableau     tab  = ros->tableau;
778e27a552bSJed Brown   const PetscInt  s    = tab->s;
7791c3436cfSJed Brown   const PetscReal *At  = tab->At,*Gamma = tab->Gamma,*ASum = tab->ASum,*GammaInv = tab->GammaInv;
7800feba352SEmil Constantinescu   const PetscReal *GammaExplicitCorr = tab->GammaExplicitCorr;
781c17803e7SJed Brown   const PetscBool *GammaZeroDiag = tab->GammaZeroDiag;
78261692a83SJed Brown   PetscScalar     *w   = ros->work;
7837d4bf2deSEmil Constantinescu   Vec             *Y   = ros->Y,Ydot = ros->Ydot,Zdot = ros->Zdot,Zstage = ros->Zstage;
784e27a552bSJed Brown   SNES            snes;
7851c3436cfSJed Brown   TSAdapt         adapt;
7861c3436cfSJed Brown   PetscInt        i,j,its,lits,reject,next_scheme;
787cdbf8f93SLisandro Dalcin   PetscReal       next_time_step;
7881c3436cfSJed Brown   PetscBool       accept;
789e27a552bSJed Brown   PetscErrorCode  ierr;
7900feba352SEmil Constantinescu   MatStructure    str;
791e27a552bSJed Brown 
792e27a552bSJed Brown   PetscFunctionBegin;
793e27a552bSJed Brown   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
794cdbf8f93SLisandro Dalcin   next_time_step = ts->time_step;
7951c3436cfSJed Brown   accept = PETSC_TRUE;
796108c343cSJed Brown   ros->status = TS_STEP_INCOMPLETE;
797e27a552bSJed Brown 
79897335746SJed Brown   for (reject=0; reject<ts->max_reject && !ts->reason; reject++,ts->reject++) {
7991c3436cfSJed Brown     const PetscReal h = ts->time_step;
800*b8123daeSJed Brown     ierr = TSPreStep(ts);CHKERRQ(ierr);
8013ca35412SEmil Constantinescu     ierr = VecCopy(ts->vec_sol,ros->VecSolPrev);CHKERRQ(ierr);/*move this at the end*/
802e27a552bSJed Brown     for (i=0; i<s; i++) {
8031c3436cfSJed Brown       ros->stage_time = ts->ptime + h*ASum[i];
804*b8123daeSJed Brown       ierr = TSPreStage(ts,ros->stage_time);CHKERRQ(ierr);
805c17803e7SJed Brown       if (GammaZeroDiag[i]) {
806c17803e7SJed Brown         ros->stage_explicit = PETSC_TRUE;
807fd96d5b0SEmil Constantinescu         ros->shift = 1./h;
808c17803e7SJed Brown       } else {
809c17803e7SJed Brown         ros->stage_explicit = PETSC_FALSE;
81061692a83SJed Brown         ros->shift = 1./(h*Gamma[i*s+i]);
811fd96d5b0SEmil Constantinescu       }
81261692a83SJed Brown 
81361692a83SJed Brown       ierr = VecCopy(ts->vec_sol,Zstage);CHKERRQ(ierr);
814de19f811SJed Brown       for (j=0; j<i; j++) w[j] = At[i*s+j];
815de19f811SJed Brown       ierr = VecMAXPY(Zstage,i,w,Y);CHKERRQ(ierr);
81661692a83SJed Brown 
81761692a83SJed Brown       for (j=0; j<i; j++) w[j] = 1./h * GammaInv[i*s+j];
81861692a83SJed Brown       ierr = VecZeroEntries(Zdot);CHKERRQ(ierr);
81961692a83SJed Brown       ierr = VecMAXPY(Zdot,i,w,Y);CHKERRQ(ierr);
82061692a83SJed Brown 
821e27a552bSJed Brown       /* Initial guess taken from last stage */
82261692a83SJed Brown       ierr = VecZeroEntries(Y[i]);CHKERRQ(ierr);
82361692a83SJed Brown 
8247d4bf2deSEmil Constantinescu       if (!ros->stage_explicit) {
82561692a83SJed Brown         if (!ros->recompute_jacobian && !i) {
82661692a83SJed Brown           ierr = SNESSetLagJacobian(snes,-2);CHKERRQ(ierr); /* Recompute the Jacobian on this solve, but not again */
82761692a83SJed Brown         }
82861692a83SJed Brown         ierr = SNESSolve(snes,PETSC_NULL,Y[i]);CHKERRQ(ierr);
829e27a552bSJed Brown         ierr = SNESGetIterationNumber(snes,&its);CHKERRQ(ierr);
830e27a552bSJed Brown         ierr = SNESGetLinearSolveIterations(snes,&lits);CHKERRQ(ierr);
8315ef26d82SJed Brown         ts->snes_its += its; ts->ksp_its += lits;
83297335746SJed Brown         ierr = TSGetAdapt(ts,&adapt);CHKERRQ(ierr);
83397335746SJed Brown         ierr = TSAdaptCheckStage(adapt,ts,&accept);CHKERRQ(ierr);
83497335746SJed Brown         if (!accept) goto reject_step;
8357d4bf2deSEmil Constantinescu       } else {
8361ce71dffSSatish Balay         Mat J,Jp;
8370feba352SEmil Constantinescu         ierr = VecZeroEntries(Ydot);CHKERRQ(ierr); /* Evaluate Y[i]=G(t,Ydot=0,Zstage) */
8380feba352SEmil Constantinescu         ierr = TSComputeIFunction(ts,ros->stage_time,Zstage,Ydot,Y[i],PETSC_FALSE);CHKERRQ(ierr);
8390feba352SEmil Constantinescu         ierr = VecScale(Y[i],-1.0);
8400feba352SEmil Constantinescu         ierr = VecAXPY(Y[i],-1.0,Zdot);CHKERRQ(ierr); /*Y[i]=F(Zstage)-Zdot[=GammaInv*Y]*/
8410feba352SEmil Constantinescu 
8420feba352SEmil Constantinescu         ierr = VecZeroEntries(Zstage);CHKERRQ(ierr); /* Zstage = GammaExplicitCorr[i,j] * Y[j] */
8430feba352SEmil Constantinescu         for (j=0; j<i; j++) w[j] = GammaExplicitCorr[i*s+j];
8440feba352SEmil Constantinescu         ierr = VecMAXPY(Zstage,i,w,Y);CHKERRQ(ierr);
8450feba352SEmil Constantinescu         /*Y[i] += Y[i] + Jac*Zstage[=Jac*GammaExplicitCorr[i,j] * Y[j]] */
8460feba352SEmil Constantinescu         str = SAME_NONZERO_PATTERN;
847ccbc64bcSJed Brown         ierr = TSGetIJacobian(ts,&J,&Jp,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
8480feba352SEmil Constantinescu         ierr = TSComputeIJacobian(ts,ros->stage_time,ts->vec_sol,Ydot,0,&J,&Jp,&str,PETSC_FALSE);CHKERRQ(ierr);
8490feba352SEmil Constantinescu         ierr = MatMult(J,Zstage,Zdot);
8500feba352SEmil Constantinescu 
8510feba352SEmil Constantinescu         ierr = VecAXPY(Y[i],-1.0,Zdot);CHKERRQ(ierr);
8520feba352SEmil Constantinescu         ierr = VecScale(Y[i],h);
8535ef26d82SJed Brown         ts->ksp_its += 1;
8547d4bf2deSEmil Constantinescu       }
855e27a552bSJed Brown     }
8561c3436cfSJed Brown     ierr = TSEvaluateStep(ts,tab->order,ts->vec_sol,PETSC_NULL);CHKERRQ(ierr);
857108c343cSJed Brown     ros->status = TS_STEP_PENDING;
858e27a552bSJed Brown 
8591c3436cfSJed Brown     /* Register only the current method as a candidate because we're not supporting multiple candidates yet. */
8601c3436cfSJed Brown     ierr = TSGetAdapt(ts,&adapt);CHKERRQ(ierr);
8611c3436cfSJed Brown     ierr = TSAdaptCandidatesClear(adapt);CHKERRQ(ierr);
8628d59e960SJed Brown     ierr = TSAdaptCandidateAdd(adapt,tab->name,tab->order,1,tab->ccfl,1.*tab->s,PETSC_TRUE);CHKERRQ(ierr);
8631c3436cfSJed Brown     ierr = TSAdaptChoose(adapt,ts,ts->time_step,&next_scheme,&next_time_step,&accept);CHKERRQ(ierr);
8641c3436cfSJed Brown     if (accept) {
8651c3436cfSJed Brown       /* ignore next_scheme for now */
866e27a552bSJed Brown       ts->ptime += ts->time_step;
867cdbf8f93SLisandro Dalcin       ts->time_step = next_time_step;
868e27a552bSJed Brown       ts->steps++;
869108c343cSJed Brown       ros->status = TS_STEP_COMPLETE;
8701c3436cfSJed Brown       break;
8711c3436cfSJed Brown     } else {                    /* Roll back the current step */
8721c3436cfSJed Brown       for (i=0; i<s; i++) w[i] = -tab->bt[i];
8731c3436cfSJed Brown       ierr = VecMAXPY(ts->vec_sol,s,w,Y);CHKERRQ(ierr);
8741c3436cfSJed Brown       ts->time_step = next_time_step;
875108c343cSJed Brown       ros->status = TS_STEP_INCOMPLETE;
8761c3436cfSJed Brown     }
877476b6736SJed Brown     reject_step: continue;
8781c3436cfSJed Brown   }
879b2ce242eSJed Brown   if (ros->status != TS_STEP_COMPLETE && !ts->reason) ts->reason = TS_DIVERGED_STEP_REJECTED;
880e27a552bSJed Brown   PetscFunctionReturn(0);
881e27a552bSJed Brown }
882e27a552bSJed Brown 
883e27a552bSJed Brown #undef __FUNCT__
884e27a552bSJed Brown #define __FUNCT__ "TSInterpolate_RosW"
885e27a552bSJed Brown static PetscErrorCode TSInterpolate_RosW(TS ts,PetscReal itime,Vec X)
886e27a552bSJed Brown {
88761692a83SJed Brown   TS_RosW        *ros = (TS_RosW*)ts->data;
888f4aed992SEmil Constantinescu   PetscInt s = ros->tableau->s,pinterp = ros->tableau->pinterp,i,j;
889f4aed992SEmil Constantinescu   PetscReal h;
890f4aed992SEmil Constantinescu   PetscReal tt,t;
891f4aed992SEmil Constantinescu   PetscScalar *bt;
892f4aed992SEmil Constantinescu   const PetscReal *Bt = ros->tableau->binterpt;
893f4aed992SEmil Constantinescu   PetscErrorCode ierr;
894f4aed992SEmil Constantinescu   const PetscReal *GammaInv = ros->tableau->GammaInv;
895f4aed992SEmil Constantinescu   PetscScalar     *w   = ros->work;
896f4aed992SEmil Constantinescu   Vec             *Y   = ros->Y;
897e27a552bSJed Brown 
898e27a552bSJed Brown   PetscFunctionBegin;
899f4aed992SEmil Constantinescu   if (!Bt) SETERRQ1(((PetscObject)ts)->comm,PETSC_ERR_SUP,"TSRosW %s does not have an interpolation formula",ros->tableau->name);
900f4aed992SEmil Constantinescu 
901f4aed992SEmil Constantinescu   switch (ros->status) {
902f4aed992SEmil Constantinescu   case TS_STEP_INCOMPLETE:
903f4aed992SEmil Constantinescu   case TS_STEP_PENDING:
904f4aed992SEmil Constantinescu     h = ts->time_step;
905f4aed992SEmil Constantinescu     t = (itime - ts->ptime)/h;
906f4aed992SEmil Constantinescu     break;
907f4aed992SEmil Constantinescu   case TS_STEP_COMPLETE:
908f4aed992SEmil Constantinescu     h = ts->time_step_prev;
909f4aed992SEmil Constantinescu     t = (itime - ts->ptime)/h + 1; /* In the interval [0,1] */
910f4aed992SEmil Constantinescu     break;
911f4aed992SEmil Constantinescu   default: SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_PLIB,"Invalid TSStepStatus");
912f4aed992SEmil Constantinescu   }
9133ca35412SEmil Constantinescu   ierr = PetscMalloc(s*sizeof(bt[0]),&bt);CHKERRQ(ierr);
914f4aed992SEmil Constantinescu   for (i=0; i<s; i++) bt[i] = 0;
915f4aed992SEmil Constantinescu   for (j=0,tt=t; j<pinterp; j++,tt*=t) {
916f4aed992SEmil Constantinescu     for (i=0; i<s; i++) {
9173ca35412SEmil Constantinescu       bt[i] += Bt[i*pinterp+j] * tt;
918f4aed992SEmil Constantinescu     }
919f4aed992SEmil Constantinescu   }
920f4aed992SEmil Constantinescu 
921f4aed992SEmil Constantinescu   /* y(t+tt*h) = y(t) + Sum bt(tt) * GammaInv * Ydot */
922f4aed992SEmil Constantinescu   /*X<-0*/
923f4aed992SEmil Constantinescu   ierr = VecZeroEntries(X);CHKERRQ(ierr);
924f4aed992SEmil Constantinescu 
925f4aed992SEmil Constantinescu   /*X<- Sum bt_i * GammaInv(i,1:i) * Y(1:i) */
9263ca35412SEmil Constantinescu   for (j=0; j<s; j++)  w[j]=0;
9273ca35412SEmil Constantinescu   for (j=0; j<s; j++) {
9283ca35412SEmil Constantinescu     for (i=j; i<s; i++) {
9293ca35412SEmil Constantinescu       w[j] +=  bt[i]*GammaInv[i*s+j];
930f4aed992SEmil Constantinescu     }
9313ca35412SEmil Constantinescu   }
9323ca35412SEmil Constantinescu   ierr = VecMAXPY(X,i,w,Y);CHKERRQ(ierr);
933f4aed992SEmil Constantinescu 
934f4aed992SEmil Constantinescu   /*X<-y(t) + X*/
9353ca35412SEmil Constantinescu   ierr = VecAXPY(X,1.0,ros->VecSolPrev);CHKERRQ(ierr);
936f4aed992SEmil Constantinescu 
937f4aed992SEmil Constantinescu   ierr = PetscFree(bt);CHKERRQ(ierr);
938f4aed992SEmil Constantinescu 
939e27a552bSJed Brown   PetscFunctionReturn(0);
940e27a552bSJed Brown }
941e27a552bSJed Brown 
942e27a552bSJed Brown /*------------------------------------------------------------*/
943e27a552bSJed Brown #undef __FUNCT__
944e27a552bSJed Brown #define __FUNCT__ "TSReset_RosW"
945e27a552bSJed Brown static PetscErrorCode TSReset_RosW(TS ts)
946e27a552bSJed Brown {
94761692a83SJed Brown   TS_RosW        *ros = (TS_RosW*)ts->data;
948e27a552bSJed Brown   PetscInt       s;
949e27a552bSJed Brown   PetscErrorCode ierr;
950e27a552bSJed Brown 
951e27a552bSJed Brown   PetscFunctionBegin;
95261692a83SJed Brown   if (!ros->tableau) PetscFunctionReturn(0);
95361692a83SJed Brown    s = ros->tableau->s;
95461692a83SJed Brown   ierr = VecDestroyVecs(s,&ros->Y);CHKERRQ(ierr);
95561692a83SJed Brown   ierr = VecDestroy(&ros->Ydot);CHKERRQ(ierr);
95661692a83SJed Brown   ierr = VecDestroy(&ros->Ystage);CHKERRQ(ierr);
95761692a83SJed Brown   ierr = VecDestroy(&ros->Zdot);CHKERRQ(ierr);
95861692a83SJed Brown   ierr = VecDestroy(&ros->Zstage);CHKERRQ(ierr);
9593ca35412SEmil Constantinescu   ierr = VecDestroy(&ros->VecSolPrev);CHKERRQ(ierr);
96061692a83SJed Brown   ierr = PetscFree(ros->work);CHKERRQ(ierr);
961e27a552bSJed Brown   PetscFunctionReturn(0);
962e27a552bSJed Brown }
963e27a552bSJed Brown 
964e27a552bSJed Brown #undef __FUNCT__
965e27a552bSJed Brown #define __FUNCT__ "TSDestroy_RosW"
966e27a552bSJed Brown static PetscErrorCode TSDestroy_RosW(TS ts)
967e27a552bSJed Brown {
968e27a552bSJed Brown   PetscErrorCode  ierr;
969e27a552bSJed Brown 
970e27a552bSJed Brown   PetscFunctionBegin;
971e27a552bSJed Brown   ierr = TSReset_RosW(ts);CHKERRQ(ierr);
972e27a552bSJed Brown   ierr = PetscFree(ts->data);CHKERRQ(ierr);
973e27a552bSJed Brown   ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSRosWGetType_C","",PETSC_NULL);CHKERRQ(ierr);
974e27a552bSJed Brown   ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSRosWSetType_C","",PETSC_NULL);CHKERRQ(ierr);
97561692a83SJed Brown   ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSRosWSetRecomputeJacobian_C","",PETSC_NULL);CHKERRQ(ierr);
976e27a552bSJed Brown   PetscFunctionReturn(0);
977e27a552bSJed Brown }
978e27a552bSJed Brown 
979e27a552bSJed Brown /*
980e27a552bSJed Brown   This defines the nonlinear equation that is to be solved with SNES
981e27a552bSJed Brown   G(U) = F[t0+Theta*dt, U, (U-U0)*shift] = 0
982e27a552bSJed Brown */
983e27a552bSJed Brown #undef __FUNCT__
984e27a552bSJed Brown #define __FUNCT__ "SNESTSFormFunction_RosW"
985e27a552bSJed Brown static PetscErrorCode SNESTSFormFunction_RosW(SNES snes,Vec X,Vec F,TS ts)
986e27a552bSJed Brown {
98761692a83SJed Brown   TS_RosW        *ros = (TS_RosW*)ts->data;
988e27a552bSJed Brown   PetscErrorCode ierr;
989e27a552bSJed Brown 
990e27a552bSJed Brown   PetscFunctionBegin;
99161692a83SJed Brown   ierr = VecWAXPY(ros->Ydot,ros->shift,X,ros->Zdot);CHKERRQ(ierr); /* Ydot = shift*X + Zdot */
99261692a83SJed Brown   ierr = VecWAXPY(ros->Ystage,1.0,X,ros->Zstage);CHKERRQ(ierr);    /* Ystage = X + Zstage */
99361692a83SJed Brown   ierr = TSComputeIFunction(ts,ros->stage_time,ros->Ystage,ros->Ydot,F,PETSC_FALSE);CHKERRQ(ierr);
994e27a552bSJed Brown   PetscFunctionReturn(0);
995e27a552bSJed Brown }
996e27a552bSJed Brown 
997e27a552bSJed Brown #undef __FUNCT__
998e27a552bSJed Brown #define __FUNCT__ "SNESTSFormJacobian_RosW"
999e27a552bSJed Brown static PetscErrorCode SNESTSFormJacobian_RosW(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *str,TS ts)
1000e27a552bSJed Brown {
100161692a83SJed Brown   TS_RosW        *ros = (TS_RosW*)ts->data;
1002e27a552bSJed Brown   PetscErrorCode ierr;
1003e27a552bSJed Brown 
1004e27a552bSJed Brown   PetscFunctionBegin;
100561692a83SJed Brown   /* ros->Ydot and ros->Ystage have already been computed in SNESTSFormFunction_RosW (SNES guarantees this) */
100661692a83SJed Brown   ierr = TSComputeIJacobian(ts,ros->stage_time,ros->Ystage,ros->Ydot,ros->shift,A,B,str,PETSC_TRUE);CHKERRQ(ierr);
1007e27a552bSJed Brown   PetscFunctionReturn(0);
1008e27a552bSJed Brown }
1009e27a552bSJed Brown 
1010e27a552bSJed Brown #undef __FUNCT__
1011e27a552bSJed Brown #define __FUNCT__ "TSSetUp_RosW"
1012e27a552bSJed Brown static PetscErrorCode TSSetUp_RosW(TS ts)
1013e27a552bSJed Brown {
101461692a83SJed Brown   TS_RosW        *ros = (TS_RosW*)ts->data;
101561692a83SJed Brown   RosWTableau    tab  = ros->tableau;
1016e27a552bSJed Brown   PetscInt       s    = tab->s;
1017e27a552bSJed Brown   PetscErrorCode ierr;
1018e27a552bSJed Brown 
1019e27a552bSJed Brown   PetscFunctionBegin;
102061692a83SJed Brown   if (!ros->tableau) {
1021e27a552bSJed Brown     ierr = TSRosWSetType(ts,TSRosWDefault);CHKERRQ(ierr);
1022e27a552bSJed Brown   }
102361692a83SJed Brown   ierr = VecDuplicateVecs(ts->vec_sol,s,&ros->Y);CHKERRQ(ierr);
102461692a83SJed Brown   ierr = VecDuplicate(ts->vec_sol,&ros->Ydot);CHKERRQ(ierr);
102561692a83SJed Brown   ierr = VecDuplicate(ts->vec_sol,&ros->Ystage);CHKERRQ(ierr);
102661692a83SJed Brown   ierr = VecDuplicate(ts->vec_sol,&ros->Zdot);CHKERRQ(ierr);
102761692a83SJed Brown   ierr = VecDuplicate(ts->vec_sol,&ros->Zstage);CHKERRQ(ierr);
10283ca35412SEmil Constantinescu   ierr = VecDuplicate(ts->vec_sol,&ros->VecSolPrev);CHKERRQ(ierr);
102961692a83SJed Brown   ierr = PetscMalloc(s*sizeof(ros->work[0]),&ros->work);CHKERRQ(ierr);
1030e27a552bSJed Brown   PetscFunctionReturn(0);
1031e27a552bSJed Brown }
1032e27a552bSJed Brown /*------------------------------------------------------------*/
1033e27a552bSJed Brown 
1034e27a552bSJed Brown #undef __FUNCT__
1035e27a552bSJed Brown #define __FUNCT__ "TSSetFromOptions_RosW"
1036e27a552bSJed Brown static PetscErrorCode TSSetFromOptions_RosW(TS ts)
1037e27a552bSJed Brown {
103861692a83SJed Brown   TS_RosW        *ros = (TS_RosW*)ts->data;
1039e27a552bSJed Brown   PetscErrorCode ierr;
104061692a83SJed Brown   char           rostype[256];
1041e27a552bSJed Brown 
1042e27a552bSJed Brown   PetscFunctionBegin;
1043e27a552bSJed Brown   ierr = PetscOptionsHead("RosW ODE solver options");CHKERRQ(ierr);
1044e27a552bSJed Brown   {
104561692a83SJed Brown     RosWTableauLink link;
1046e27a552bSJed Brown     PetscInt count,choice;
1047e27a552bSJed Brown     PetscBool flg;
1048e27a552bSJed Brown     const char **namelist;
104961692a83SJed Brown     SNES snes;
105061692a83SJed Brown 
105161692a83SJed Brown     ierr = PetscStrncpy(rostype,TSRosWDefault,sizeof rostype);CHKERRQ(ierr);
105261692a83SJed Brown     for (link=RosWTableauList,count=0; link; link=link->next,count++) ;
1053e27a552bSJed Brown     ierr = PetscMalloc(count*sizeof(char*),&namelist);CHKERRQ(ierr);
105461692a83SJed Brown     for (link=RosWTableauList,count=0; link; link=link->next,count++) namelist[count] = link->tab.name;
105561692a83SJed Brown     ierr = PetscOptionsEList("-ts_rosw_type","Family of Rosenbrock-W method","TSRosWSetType",(const char*const*)namelist,count,rostype,&choice,&flg);CHKERRQ(ierr);
105661692a83SJed Brown     ierr = TSRosWSetType(ts,flg ? namelist[choice] : rostype);CHKERRQ(ierr);
1057e27a552bSJed Brown     ierr = PetscFree(namelist);CHKERRQ(ierr);
105861692a83SJed Brown 
105961692a83SJed Brown     ierr = PetscOptionsBool("-ts_rosw_recompute_jacobian","Recompute the Jacobian at each stage","TSRosWSetRecomputeJacobian",ros->recompute_jacobian,&ros->recompute_jacobian,PETSC_NULL);CHKERRQ(ierr);
106061692a83SJed Brown 
106161692a83SJed Brown     /* Rosenbrock methods are linearly implicit, so set that unless the user has specifically asked for something else */
106261692a83SJed Brown     ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
106361692a83SJed Brown     if (!((PetscObject)snes)->type_name) {
106461692a83SJed Brown       ierr = SNESSetType(snes,SNESKSPONLY);CHKERRQ(ierr);
106561692a83SJed Brown     }
106661692a83SJed Brown     ierr = SNESSetFromOptions(snes);CHKERRQ(ierr);
1067e27a552bSJed Brown   }
1068e27a552bSJed Brown   ierr = PetscOptionsTail();CHKERRQ(ierr);
1069e27a552bSJed Brown   PetscFunctionReturn(0);
1070e27a552bSJed Brown }
1071e27a552bSJed Brown 
1072e27a552bSJed Brown #undef __FUNCT__
1073e27a552bSJed Brown #define __FUNCT__ "PetscFormatRealArray"
1074e27a552bSJed Brown static PetscErrorCode PetscFormatRealArray(char buf[],size_t len,const char *fmt,PetscInt n,const PetscReal x[])
1075e27a552bSJed Brown {
1076e27a552bSJed Brown   PetscErrorCode ierr;
1077e408995aSJed Brown   PetscInt i;
1078e408995aSJed Brown   size_t left,count;
1079e27a552bSJed Brown   char *p;
1080e27a552bSJed Brown 
1081e27a552bSJed Brown   PetscFunctionBegin;
1082e408995aSJed Brown   for (i=0,p=buf,left=len; i<n; i++) {
1083e408995aSJed Brown     ierr = PetscSNPrintfCount(p,left,fmt,&count,x[i]);CHKERRQ(ierr);
1084e27a552bSJed Brown     if (count >= left) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Insufficient space in buffer");
1085e27a552bSJed Brown     left -= count;
1086e27a552bSJed Brown     p += count;
1087e27a552bSJed Brown     *p++ = ' ';
1088e27a552bSJed Brown   }
1089e27a552bSJed Brown   p[i ? 0 : -1] = 0;
1090e27a552bSJed Brown   PetscFunctionReturn(0);
1091e27a552bSJed Brown }
1092e27a552bSJed Brown 
1093e27a552bSJed Brown #undef __FUNCT__
1094e27a552bSJed Brown #define __FUNCT__ "TSView_RosW"
1095e27a552bSJed Brown static PetscErrorCode TSView_RosW(TS ts,PetscViewer viewer)
1096e27a552bSJed Brown {
109761692a83SJed Brown   TS_RosW        *ros = (TS_RosW*)ts->data;
109861692a83SJed Brown   RosWTableau    tab  = ros->tableau;
1099e27a552bSJed Brown   PetscBool      iascii;
1100e27a552bSJed Brown   PetscErrorCode ierr;
1101e27a552bSJed Brown 
1102e27a552bSJed Brown   PetscFunctionBegin;
1103251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1104e27a552bSJed Brown   if (iascii) {
110561692a83SJed Brown     const TSRosWType rostype;
1106e408995aSJed Brown     PetscInt i;
1107e408995aSJed Brown     PetscReal abscissa[512];
1108e27a552bSJed Brown     char buf[512];
110961692a83SJed Brown     ierr = TSRosWGetType(ts,&rostype);CHKERRQ(ierr);
111061692a83SJed Brown     ierr = PetscViewerASCIIPrintf(viewer,"  Rosenbrock-W %s\n",rostype);CHKERRQ(ierr);
1111e408995aSJed Brown     ierr = PetscFormatRealArray(buf,sizeof buf,"% 8.6f",tab->s,tab->ASum);CHKERRQ(ierr);
111261692a83SJed Brown     ierr = PetscViewerASCIIPrintf(viewer,"  Abscissa of A       = %s\n",buf);CHKERRQ(ierr);
1113e408995aSJed Brown     for (i=0; i<tab->s; i++) abscissa[i] = tab->ASum[i] + tab->Gamma[i];
1114e408995aSJed Brown     ierr = PetscFormatRealArray(buf,sizeof buf,"% 8.6f",tab->s,abscissa);CHKERRQ(ierr);
1115e408995aSJed Brown     ierr = PetscViewerASCIIPrintf(viewer,"  Abscissa of A+Gamma = %s\n",buf);CHKERRQ(ierr);
1116e27a552bSJed Brown   }
1117e27a552bSJed Brown   ierr = SNESView(ts->snes,viewer);CHKERRQ(ierr);
1118e27a552bSJed Brown   PetscFunctionReturn(0);
1119e27a552bSJed Brown }
1120e27a552bSJed Brown 
1121e27a552bSJed Brown #undef __FUNCT__
1122e27a552bSJed Brown #define __FUNCT__ "TSRosWSetType"
1123e27a552bSJed Brown /*@C
112461692a83SJed Brown   TSRosWSetType - Set the type of Rosenbrock-W scheme
1125e27a552bSJed Brown 
1126e27a552bSJed Brown   Logically collective
1127e27a552bSJed Brown 
1128e27a552bSJed Brown   Input Parameter:
1129e27a552bSJed Brown +  ts - timestepping context
113061692a83SJed Brown -  rostype - type of Rosenbrock-W scheme
1131e27a552bSJed Brown 
1132020d8f30SJed Brown   Level: beginner
1133e27a552bSJed Brown 
1134020d8f30SJed Brown .seealso: TSRosWGetType(), TSROSW, TSROSW2M, TSROSW2P, TSROSWRA3PW, TSROSWRA34PW2, TSROSWRODAS3, TSROSWSANDU3, TSROSWASSP3P3S1C, TSROSWLASSP3P4S2C, TSROSWLLSSP3P4S2C, TSROSWARK3
1135e27a552bSJed Brown @*/
113661692a83SJed Brown PetscErrorCode TSRosWSetType(TS ts,const TSRosWType rostype)
1137e27a552bSJed Brown {
1138e27a552bSJed Brown   PetscErrorCode ierr;
1139e27a552bSJed Brown 
1140e27a552bSJed Brown   PetscFunctionBegin;
1141e27a552bSJed Brown   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
114261692a83SJed Brown   ierr = PetscTryMethod(ts,"TSRosWSetType_C",(TS,const TSRosWType),(ts,rostype));CHKERRQ(ierr);
1143e27a552bSJed Brown   PetscFunctionReturn(0);
1144e27a552bSJed Brown }
1145e27a552bSJed Brown 
1146e27a552bSJed Brown #undef __FUNCT__
1147e27a552bSJed Brown #define __FUNCT__ "TSRosWGetType"
1148e27a552bSJed Brown /*@C
114961692a83SJed Brown   TSRosWGetType - Get the type of Rosenbrock-W scheme
1150e27a552bSJed Brown 
1151e27a552bSJed Brown   Logically collective
1152e27a552bSJed Brown 
1153e27a552bSJed Brown   Input Parameter:
1154e27a552bSJed Brown .  ts - timestepping context
1155e27a552bSJed Brown 
1156e27a552bSJed Brown   Output Parameter:
115761692a83SJed Brown .  rostype - type of Rosenbrock-W scheme
1158e27a552bSJed Brown 
1159e27a552bSJed Brown   Level: intermediate
1160e27a552bSJed Brown 
1161e27a552bSJed Brown .seealso: TSRosWGetType()
1162e27a552bSJed Brown @*/
116361692a83SJed Brown PetscErrorCode TSRosWGetType(TS ts,const TSRosWType *rostype)
1164e27a552bSJed Brown {
1165e27a552bSJed Brown   PetscErrorCode ierr;
1166e27a552bSJed Brown 
1167e27a552bSJed Brown   PetscFunctionBegin;
1168e27a552bSJed Brown   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
116961692a83SJed Brown   ierr = PetscUseMethod(ts,"TSRosWGetType_C",(TS,const TSRosWType*),(ts,rostype));CHKERRQ(ierr);
1170e27a552bSJed Brown   PetscFunctionReturn(0);
1171e27a552bSJed Brown }
1172e27a552bSJed Brown 
1173e27a552bSJed Brown #undef __FUNCT__
117461692a83SJed Brown #define __FUNCT__ "TSRosWSetRecomputeJacobian"
1175e27a552bSJed Brown /*@C
117661692a83SJed Brown   TSRosWSetRecomputeJacobian - Set whether to recompute the Jacobian at each stage. The default is to update the Jacobian once per step.
1177e27a552bSJed Brown 
1178e27a552bSJed Brown   Logically collective
1179e27a552bSJed Brown 
1180e27a552bSJed Brown   Input Parameter:
1181e27a552bSJed Brown +  ts - timestepping context
118261692a83SJed Brown -  flg - PETSC_TRUE to recompute the Jacobian at each stage
1183e27a552bSJed Brown 
1184e27a552bSJed Brown   Level: intermediate
1185e27a552bSJed Brown 
1186e27a552bSJed Brown .seealso: TSRosWGetType()
1187e27a552bSJed Brown @*/
118861692a83SJed Brown PetscErrorCode TSRosWSetRecomputeJacobian(TS ts,PetscBool flg)
1189e27a552bSJed Brown {
1190e27a552bSJed Brown   PetscErrorCode ierr;
1191e27a552bSJed Brown 
1192e27a552bSJed Brown   PetscFunctionBegin;
1193e27a552bSJed Brown   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
119461692a83SJed Brown   ierr = PetscTryMethod(ts,"TSRosWSetRecomputeJacobian_C",(TS,PetscBool),(ts,flg));CHKERRQ(ierr);
1195e27a552bSJed Brown   PetscFunctionReturn(0);
1196e27a552bSJed Brown }
1197e27a552bSJed Brown 
1198e27a552bSJed Brown EXTERN_C_BEGIN
1199e27a552bSJed Brown #undef __FUNCT__
1200e27a552bSJed Brown #define __FUNCT__ "TSRosWGetType_RosW"
120161692a83SJed Brown PetscErrorCode  TSRosWGetType_RosW(TS ts,const TSRosWType *rostype)
1202e27a552bSJed Brown {
120361692a83SJed Brown   TS_RosW        *ros = (TS_RosW*)ts->data;
1204e27a552bSJed Brown   PetscErrorCode ierr;
1205e27a552bSJed Brown 
1206e27a552bSJed Brown   PetscFunctionBegin;
120761692a83SJed Brown   if (!ros->tableau) {ierr = TSRosWSetType(ts,TSRosWDefault);CHKERRQ(ierr);}
120861692a83SJed Brown   *rostype = ros->tableau->name;
1209e27a552bSJed Brown   PetscFunctionReturn(0);
1210e27a552bSJed Brown }
1211e27a552bSJed Brown #undef __FUNCT__
1212e27a552bSJed Brown #define __FUNCT__ "TSRosWSetType_RosW"
121361692a83SJed Brown PetscErrorCode  TSRosWSetType_RosW(TS ts,const TSRosWType rostype)
1214e27a552bSJed Brown {
121561692a83SJed Brown   TS_RosW         *ros = (TS_RosW*)ts->data;
1216e27a552bSJed Brown   PetscErrorCode  ierr;
1217e27a552bSJed Brown   PetscBool       match;
121861692a83SJed Brown   RosWTableauLink link;
1219e27a552bSJed Brown 
1220e27a552bSJed Brown   PetscFunctionBegin;
122161692a83SJed Brown   if (ros->tableau) {
122261692a83SJed Brown     ierr = PetscStrcmp(ros->tableau->name,rostype,&match);CHKERRQ(ierr);
1223e27a552bSJed Brown     if (match) PetscFunctionReturn(0);
1224e27a552bSJed Brown   }
122561692a83SJed Brown   for (link = RosWTableauList; link; link=link->next) {
122661692a83SJed Brown     ierr = PetscStrcmp(link->tab.name,rostype,&match);CHKERRQ(ierr);
1227e27a552bSJed Brown     if (match) {
1228e27a552bSJed Brown       ierr = TSReset_RosW(ts);CHKERRQ(ierr);
122961692a83SJed Brown       ros->tableau = &link->tab;
1230e27a552bSJed Brown       PetscFunctionReturn(0);
1231e27a552bSJed Brown     }
1232e27a552bSJed Brown   }
123361692a83SJed Brown   SETERRQ1(((PetscObject)ts)->comm,PETSC_ERR_ARG_UNKNOWN_TYPE,"Could not find '%s'",rostype);
1234e27a552bSJed Brown   PetscFunctionReturn(0);
1235e27a552bSJed Brown }
123661692a83SJed Brown 
1237e27a552bSJed Brown #undef __FUNCT__
123861692a83SJed Brown #define __FUNCT__ "TSRosWSetRecomputeJacobian_RosW"
123961692a83SJed Brown PetscErrorCode  TSRosWSetRecomputeJacobian_RosW(TS ts,PetscBool flg)
1240e27a552bSJed Brown {
124161692a83SJed Brown   TS_RosW *ros = (TS_RosW*)ts->data;
1242e27a552bSJed Brown 
1243e27a552bSJed Brown   PetscFunctionBegin;
124461692a83SJed Brown   ros->recompute_jacobian = flg;
1245e27a552bSJed Brown   PetscFunctionReturn(0);
1246e27a552bSJed Brown }
1247e27a552bSJed Brown EXTERN_C_END
1248e27a552bSJed Brown 
1249e27a552bSJed Brown /* ------------------------------------------------------------ */
1250e27a552bSJed Brown /*MC
1251020d8f30SJed Brown       TSROSW - ODE solver using Rosenbrock-W schemes
1252e27a552bSJed Brown 
1253e27a552bSJed Brown   These methods are intended for problems with well-separated time scales, especially when a slow scale is strongly
1254e27a552bSJed Brown   nonlinear such that it is expensive to solve with a fully implicit method. The user should provide the stiff part
1255e27a552bSJed Brown   of the equation using TSSetIFunction() and the non-stiff part with TSSetRHSFunction().
1256e27a552bSJed Brown 
1257e27a552bSJed Brown   Notes:
125861692a83SJed Brown   This method currently only works with autonomous ODE and DAE.
125961692a83SJed Brown 
126061692a83SJed Brown   Developer notes:
126161692a83SJed Brown   Rosenbrock-W methods are typically specified for autonomous ODE
126261692a83SJed Brown 
126361692a83SJed Brown $  xdot = f(x)
126461692a83SJed Brown 
126561692a83SJed Brown   by the stage equations
126661692a83SJed Brown 
126761692a83SJed Brown $  k_i = h f(x_0 + sum_j alpha_ij k_j) + h J sum_j gamma_ij k_j
126861692a83SJed Brown 
126961692a83SJed Brown   and step completion formula
127061692a83SJed Brown 
127161692a83SJed Brown $  x_1 = x_0 + sum_j b_j k_j
127261692a83SJed Brown 
127361692a83SJed Brown   with step size h and coefficients alpha_ij, gamma_ij, and b_i. Implementing the method in this form would require f(x)
127461692a83SJed Brown   and the Jacobian J to be available, in addition to the shifted matrix I - h gamma_ii J. Following Hairer and Wanner,
127561692a83SJed Brown   we define new variables for the stage equations
127661692a83SJed Brown 
127761692a83SJed Brown $  y_i = gamma_ij k_j
127861692a83SJed Brown 
127961692a83SJed Brown   The k_j can be recovered because Gamma is invertible. Let C be the lower triangular part of Gamma^{-1} and define
128061692a83SJed Brown 
128161692a83SJed Brown $  A = Alpha Gamma^{-1}, bt^T = b^T Gamma^{-i}
128261692a83SJed Brown 
128361692a83SJed Brown   to rewrite the method as
128461692a83SJed Brown 
128561692a83SJed 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
128661692a83SJed Brown $  x_1 = x_0 + sum_j bt_j y_j
128761692a83SJed Brown 
128861692a83SJed Brown    where we have introduced the mass matrix M. Continue by defining
128961692a83SJed Brown 
129061692a83SJed Brown $  ydot_i = 1/(h gamma_ii) y_i - sum_j (c_ij/h) y_j
129161692a83SJed Brown 
129261692a83SJed Brown    or, more compactly in tensor notation
129361692a83SJed Brown 
129461692a83SJed Brown $  Ydot = 1/h (Gamma^{-1} \otimes I) Y .
129561692a83SJed Brown 
129661692a83SJed Brown    Note that Gamma^{-1} is lower triangular. With this definition of Ydot in terms of known quantities and the current
129761692a83SJed Brown    stage y_i, the stage equations reduce to performing one Newton step (typically with a lagged Jacobian) on the
129861692a83SJed Brown    equation
129961692a83SJed Brown 
130061692a83SJed Brown $  g(x_0 + sum_j a_ij y_j + y_i, ydot_i) = 0
130161692a83SJed Brown 
130261692a83SJed Brown    with initial guess y_i = 0.
1303e27a552bSJed Brown 
1304e27a552bSJed Brown   Level: beginner
1305e27a552bSJed Brown 
1306020d8f30SJed Brown .seealso:  TSCreate(), TS, TSSetType(), TSRosWSetType(), TSRosWRegister()
1307e27a552bSJed Brown 
1308e27a552bSJed Brown M*/
1309e27a552bSJed Brown EXTERN_C_BEGIN
1310e27a552bSJed Brown #undef __FUNCT__
1311e27a552bSJed Brown #define __FUNCT__ "TSCreate_RosW"
1312e27a552bSJed Brown PetscErrorCode  TSCreate_RosW(TS ts)
1313e27a552bSJed Brown {
131461692a83SJed Brown   TS_RosW        *ros;
1315e27a552bSJed Brown   PetscErrorCode ierr;
1316e27a552bSJed Brown 
1317e27a552bSJed Brown   PetscFunctionBegin;
1318e27a552bSJed Brown #if !defined(PETSC_USE_DYNAMIC_LIBRARIES)
1319e27a552bSJed Brown   ierr = TSRosWInitializePackage(PETSC_NULL);CHKERRQ(ierr);
1320e27a552bSJed Brown #endif
1321e27a552bSJed Brown 
1322e27a552bSJed Brown   ts->ops->reset          = TSReset_RosW;
1323e27a552bSJed Brown   ts->ops->destroy        = TSDestroy_RosW;
1324e27a552bSJed Brown   ts->ops->view           = TSView_RosW;
1325e27a552bSJed Brown   ts->ops->setup          = TSSetUp_RosW;
1326e27a552bSJed Brown   ts->ops->step           = TSStep_RosW;
1327e27a552bSJed Brown   ts->ops->interpolate    = TSInterpolate_RosW;
13281c3436cfSJed Brown   ts->ops->evaluatestep   = TSEvaluateStep_RosW;
1329e27a552bSJed Brown   ts->ops->setfromoptions = TSSetFromOptions_RosW;
1330e27a552bSJed Brown   ts->ops->snesfunction   = SNESTSFormFunction_RosW;
1331e27a552bSJed Brown   ts->ops->snesjacobian   = SNESTSFormJacobian_RosW;
1332e27a552bSJed Brown 
133361692a83SJed Brown   ierr = PetscNewLog(ts,TS_RosW,&ros);CHKERRQ(ierr);
133461692a83SJed Brown   ts->data = (void*)ros;
1335e27a552bSJed Brown 
1336e27a552bSJed Brown   ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSRosWGetType_C","TSRosWGetType_RosW",TSRosWGetType_RosW);CHKERRQ(ierr);
1337e27a552bSJed Brown   ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSRosWSetType_C","TSRosWSetType_RosW",TSRosWSetType_RosW);CHKERRQ(ierr);
133861692a83SJed Brown   ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSRosWSetRecomputeJacobian_C","TSRosWSetRecomputeJacobian_RosW",TSRosWSetRecomputeJacobian_RosW);CHKERRQ(ierr);
1339e27a552bSJed Brown   PetscFunctionReturn(0);
1340e27a552bSJed Brown }
1341e27a552bSJed Brown EXTERN_C_END
1342