xref: /petsc/src/ts/impls/rosw/rosw.c (revision e408995a0071fdf06114d394b0caf1044a1a91b4)
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 
1761692a83SJed Brown static const TSRosWType TSRosWDefault = TSROSW2P;
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 */
26e27a552bSJed Brown   PetscInt pinterp;             /* Interpolation order */
2761692a83SJed Brown   PetscReal *A;                 /* Propagation table, strictly lower triangular */
2861692a83SJed Brown   PetscReal *Gamma;             /* Stage table, lower triangular with nonzero diagonal */
2961692a83SJed Brown   PetscReal *b;                 /* Step completion table */
3061692a83SJed Brown   PetscReal *ASum;              /* Row sum of A */
3161692a83SJed Brown   PetscReal *GammaSum;          /* Row sum of Gamma, only needed for non-autonomous systems */
3261692a83SJed Brown   PetscReal *At;                /* Propagation table in transformed variables */
3361692a83SJed Brown   PetscReal *bt;                /* Step completion table in transformed variables  */
3461692a83SJed Brown   PetscReal *GammaInv;          /* Inverse of Gamma, used for transformed variables */
35e27a552bSJed Brown };
3661692a83SJed Brown typedef struct _RosWTableauLink *RosWTableauLink;
3761692a83SJed Brown struct _RosWTableauLink {
3861692a83SJed Brown   struct _RosWTableau tab;
3961692a83SJed Brown   RosWTableauLink next;
40e27a552bSJed Brown };
4161692a83SJed Brown static RosWTableauLink RosWTableauList;
42e27a552bSJed Brown 
43e27a552bSJed Brown typedef struct {
4461692a83SJed Brown   RosWTableau tableau;
4561692a83SJed Brown   Vec         *Y;               /* States computed during the step, used to complete the step */
46e27a552bSJed Brown   Vec         Ydot;             /* Work vector holding Ydot during residual evaluation */
4761692a83SJed Brown   Vec         Ystage;           /* Work vector for the state value at each stage */
4861692a83SJed Brown   Vec         Zdot;             /* Ydot = Zdot + shift*Y */
4961692a83SJed Brown   Vec         Zstage;           /* Y = Zstage + Y */
50e27a552bSJed Brown   PetscScalar *work;            /* Scalar work */
51e27a552bSJed Brown   PetscReal   shift;
52e27a552bSJed Brown   PetscReal   stage_time;
5361692a83SJed Brown   PetscBool   recompute_jacobian; /* Recompute the Jacobian at each stage, default is to freeze the Jacobian at the start of each step */
54e27a552bSJed Brown } TS_RosW;
55e27a552bSJed Brown 
56e27a552bSJed Brown #undef __FUNCT__
57e27a552bSJed Brown #define __FUNCT__ "TSRosWRegisterAll"
58e27a552bSJed Brown /*@C
59e27a552bSJed Brown   TSRosWRegisterAll - Registers all of the additive Runge-Kutta implicit-explicit methods in TSRosW
60e27a552bSJed Brown 
61e27a552bSJed Brown   Not Collective, but should be called by all processes which will need the schemes to be registered
62e27a552bSJed Brown 
63e27a552bSJed Brown   Level: advanced
64e27a552bSJed Brown 
65e27a552bSJed Brown .keywords: TS, TSRosW, register, all
66e27a552bSJed Brown 
67e27a552bSJed Brown .seealso:  TSRosWRegisterDestroy()
68e27a552bSJed Brown @*/
69e27a552bSJed Brown PetscErrorCode TSRosWRegisterAll(void)
70e27a552bSJed Brown {
71e27a552bSJed Brown   PetscErrorCode ierr;
72e27a552bSJed Brown 
73e27a552bSJed Brown   PetscFunctionBegin;
74e27a552bSJed Brown   if (TSRosWRegisterAllCalled) PetscFunctionReturn(0);
75e27a552bSJed Brown   TSRosWRegisterAllCalled = PETSC_TRUE;
76e27a552bSJed Brown 
77e27a552bSJed Brown   {
7861692a83SJed Brown     const PetscReal g = 1. + 1./PetscSqrtReal(2.0);
79e27a552bSJed Brown     const PetscReal
8061692a83SJed Brown       A[2][2] = {{0,0}, {1.,0}},
8161692a83SJed Brown       Gamma[2][2] = {{g,0}, {-2.*g,g}},
8261692a83SJed Brown       b[2] = {0.5,0.5};
8361692a83SJed Brown     ierr = TSRosWRegister(TSROSW2P,2,2,&A[0][0],&Gamma[0][0],b);CHKERRQ(ierr);
84e27a552bSJed Brown   }
85e27a552bSJed Brown   {
8661692a83SJed Brown     const PetscReal g = 1. - 1./PetscSqrtReal(2.0);
87e27a552bSJed Brown     const PetscReal
8861692a83SJed Brown       A[2][2] = {{0,0}, {1.,0}},
8961692a83SJed Brown       Gamma[2][2] = {{g,0}, {-2.*g,g}},
9061692a83SJed Brown       b[2] = {0.5,0.5};
9161692a83SJed Brown     ierr = TSRosWRegister(TSROSW2M,2,2,&A[0][0],&Gamma[0][0],b);CHKERRQ(ierr);
92e27a552bSJed Brown   }
93e27a552bSJed Brown   PetscFunctionReturn(0);
94e27a552bSJed Brown }
95e27a552bSJed Brown 
96e27a552bSJed Brown #undef __FUNCT__
97e27a552bSJed Brown #define __FUNCT__ "TSRosWRegisterDestroy"
98e27a552bSJed Brown /*@C
99e27a552bSJed Brown    TSRosWRegisterDestroy - Frees the list of schemes that were registered by TSRosWRegister().
100e27a552bSJed Brown 
101e27a552bSJed Brown    Not Collective
102e27a552bSJed Brown 
103e27a552bSJed Brown    Level: advanced
104e27a552bSJed Brown 
105e27a552bSJed Brown .keywords: TSRosW, register, destroy
106e27a552bSJed Brown .seealso: TSRosWRegister(), TSRosWRegisterAll(), TSRosWRegisterDynamic()
107e27a552bSJed Brown @*/
108e27a552bSJed Brown PetscErrorCode TSRosWRegisterDestroy(void)
109e27a552bSJed Brown {
110e27a552bSJed Brown   PetscErrorCode ierr;
11161692a83SJed Brown   RosWTableauLink link;
112e27a552bSJed Brown 
113e27a552bSJed Brown   PetscFunctionBegin;
11461692a83SJed Brown   while ((link = RosWTableauList)) {
11561692a83SJed Brown     RosWTableau t = &link->tab;
11661692a83SJed Brown     RosWTableauList = link->next;
11761692a83SJed Brown     ierr = PetscFree5(t->A,t->Gamma,t->b,t->ASum,t->GammaSum);CHKERRQ(ierr);
11861692a83SJed Brown     ierr = PetscFree3(t->At,t->bt,t->GammaInv);CHKERRQ(ierr);
119e27a552bSJed Brown     ierr = PetscFree(t->name);CHKERRQ(ierr);
120e27a552bSJed Brown     ierr = PetscFree(link);CHKERRQ(ierr);
121e27a552bSJed Brown   }
122e27a552bSJed Brown   TSRosWRegisterAllCalled = PETSC_FALSE;
123e27a552bSJed Brown   PetscFunctionReturn(0);
124e27a552bSJed Brown }
125e27a552bSJed Brown 
126e27a552bSJed Brown #undef __FUNCT__
127e27a552bSJed Brown #define __FUNCT__ "TSRosWInitializePackage"
128e27a552bSJed Brown /*@C
129e27a552bSJed Brown   TSRosWInitializePackage - This function initializes everything in the TSRosW package. It is called
130e27a552bSJed Brown   from PetscDLLibraryRegister() when using dynamic libraries, and on the first call to TSCreate_RosW()
131e27a552bSJed Brown   when using static libraries.
132e27a552bSJed Brown 
133e27a552bSJed Brown   Input Parameter:
134e27a552bSJed Brown   path - The dynamic library path, or PETSC_NULL
135e27a552bSJed Brown 
136e27a552bSJed Brown   Level: developer
137e27a552bSJed Brown 
138e27a552bSJed Brown .keywords: TS, TSRosW, initialize, package
139e27a552bSJed Brown .seealso: PetscInitialize()
140e27a552bSJed Brown @*/
141e27a552bSJed Brown PetscErrorCode TSRosWInitializePackage(const char path[])
142e27a552bSJed Brown {
143e27a552bSJed Brown   PetscErrorCode ierr;
144e27a552bSJed Brown 
145e27a552bSJed Brown   PetscFunctionBegin;
146e27a552bSJed Brown   if (TSRosWPackageInitialized) PetscFunctionReturn(0);
147e27a552bSJed Brown   TSRosWPackageInitialized = PETSC_TRUE;
148e27a552bSJed Brown   ierr = TSRosWRegisterAll();CHKERRQ(ierr);
149e27a552bSJed Brown   ierr = PetscRegisterFinalize(TSRosWFinalizePackage);CHKERRQ(ierr);
150e27a552bSJed Brown   PetscFunctionReturn(0);
151e27a552bSJed Brown }
152e27a552bSJed Brown 
153e27a552bSJed Brown #undef __FUNCT__
154e27a552bSJed Brown #define __FUNCT__ "TSRosWFinalizePackage"
155e27a552bSJed Brown /*@C
156e27a552bSJed Brown   TSRosWFinalizePackage - This function destroys everything in the TSRosW package. It is
157e27a552bSJed Brown   called from PetscFinalize().
158e27a552bSJed Brown 
159e27a552bSJed Brown   Level: developer
160e27a552bSJed Brown 
161e27a552bSJed Brown .keywords: Petsc, destroy, package
162e27a552bSJed Brown .seealso: PetscFinalize()
163e27a552bSJed Brown @*/
164e27a552bSJed Brown PetscErrorCode TSRosWFinalizePackage(void)
165e27a552bSJed Brown {
166e27a552bSJed Brown   PetscErrorCode ierr;
167e27a552bSJed Brown 
168e27a552bSJed Brown   PetscFunctionBegin;
169e27a552bSJed Brown   TSRosWPackageInitialized = PETSC_FALSE;
170e27a552bSJed Brown   ierr = TSRosWRegisterDestroy();CHKERRQ(ierr);
171e27a552bSJed Brown   PetscFunctionReturn(0);
172e27a552bSJed Brown }
173e27a552bSJed Brown 
174e27a552bSJed Brown #undef __FUNCT__
175e27a552bSJed Brown #define __FUNCT__ "TSRosWRegister"
176e27a552bSJed Brown /*@C
17761692a83SJed Brown    TSRosWRegister - register a Rosenbrock W scheme by providing the entries in the Butcher tableau and optionally embedded approximations and interpolation
178e27a552bSJed Brown 
179e27a552bSJed Brown    Not Collective, but the same schemes should be registered on all processes on which they will be used
180e27a552bSJed Brown 
181e27a552bSJed Brown    Input Parameters:
182e27a552bSJed Brown +  name - identifier for method
183e27a552bSJed Brown .  order - approximation order of method
184e27a552bSJed Brown .  s - number of stages, this is the dimension of the matrices below
18561692a83SJed Brown .  A - Table of propagated stage coefficients (dimension s*s, row-major), strictly lower triangular
18661692a83SJed Brown .  Gamma - Table of coefficients in implicit stage equations (dimension s*s, row-major), lower triangular with nonzero diagonal
18761692a83SJed Brown -  b - Step completion table (dimension s)
188e27a552bSJed Brown 
189e27a552bSJed Brown    Notes:
19061692a83SJed Brown    Several Rosenbrock W methods are provided, this function is only needed to create new methods.
191e27a552bSJed Brown 
192e27a552bSJed Brown    Level: advanced
193e27a552bSJed Brown 
194e27a552bSJed Brown .keywords: TS, register
195e27a552bSJed Brown 
196e27a552bSJed Brown .seealso: TSRosW
197e27a552bSJed Brown @*/
198e27a552bSJed Brown PetscErrorCode TSRosWRegister(const TSRosWType name,PetscInt order,PetscInt s,
19961692a83SJed Brown                               const PetscReal A[],const PetscReal Gamma[],const PetscReal b[])
200e27a552bSJed Brown {
201e27a552bSJed Brown   PetscErrorCode ierr;
20261692a83SJed Brown   RosWTableauLink link;
20361692a83SJed Brown   RosWTableau t;
20461692a83SJed Brown   PetscInt i,j,k;
20561692a83SJed Brown   PetscScalar *GammaInv;
206e27a552bSJed Brown 
207e27a552bSJed Brown   PetscFunctionBegin;
208e27a552bSJed Brown   ierr = PetscMalloc(sizeof(*link),&link);CHKERRQ(ierr);
209e27a552bSJed Brown   ierr = PetscMemzero(link,sizeof(*link));CHKERRQ(ierr);
210e27a552bSJed Brown   t = &link->tab;
211e27a552bSJed Brown   ierr = PetscStrallocpy(name,&t->name);CHKERRQ(ierr);
212e27a552bSJed Brown   t->order = order;
213e27a552bSJed Brown   t->s = s;
21461692a83SJed 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);
21561692a83SJed Brown   ierr = PetscMalloc3(s*s,PetscReal,&t->At,s,PetscReal,&t->bt,s*s,PetscReal,&t->GammaInv);CHKERRQ(ierr);
216e27a552bSJed Brown   ierr = PetscMemcpy(t->A,A,s*s*sizeof(A[0]));CHKERRQ(ierr);
21761692a83SJed Brown   ierr = PetscMemcpy(t->Gamma,Gamma,s*s*sizeof(Gamma[0]));CHKERRQ(ierr);
21861692a83SJed Brown   ierr = PetscMemcpy(t->b,b,s*sizeof(b[0]));CHKERRQ(ierr);
21961692a83SJed Brown   for (i=0; i<s; i++) {
22061692a83SJed Brown     t->ASum[i] = 0;
22161692a83SJed Brown     t->GammaSum[i] = 0;
22261692a83SJed Brown     for (j=0; j<s; j++) {
22361692a83SJed Brown       t->ASum[i] += A[i*s+j];
22461692a83SJed Brown       t->GammaSum[i] = Gamma[i*s+j];
22561692a83SJed Brown     }
22661692a83SJed Brown   }
22761692a83SJed Brown   ierr = PetscMalloc(s*s*sizeof(PetscScalar),&GammaInv);CHKERRQ(ierr); /* Need to use Scalar for inverse, then convert back to Real */
22861692a83SJed Brown   for (i=0; i<s*s; i++) GammaInv[i] = Gamma[i];
22961692a83SJed Brown   switch (s) {
23061692a83SJed Brown   case 1: GammaInv[0] = 1./GammaInv[0]; break;
23161692a83SJed Brown   case 2: ierr = Kernel_A_gets_inverse_A_2(GammaInv,0);CHKERRQ(ierr); break;
23261692a83SJed Brown   case 3: ierr = Kernel_A_gets_inverse_A_3(GammaInv,0);CHKERRQ(ierr); break;
23361692a83SJed Brown   case 4: ierr = Kernel_A_gets_inverse_A_4(GammaInv,0);CHKERRQ(ierr); break;
23461692a83SJed Brown   case 5: {
23561692a83SJed Brown     PetscInt ipvt5[5];
23661692a83SJed Brown     MatScalar work5[5*5];
23761692a83SJed Brown     ierr = Kernel_A_gets_inverse_A_5(GammaInv,ipvt5,work5,0);CHKERRQ(ierr); break;
23861692a83SJed Brown   }
23961692a83SJed Brown   case 6: ierr = Kernel_A_gets_inverse_A_6(GammaInv,0);CHKERRQ(ierr); break;
24061692a83SJed Brown   case 7: ierr = Kernel_A_gets_inverse_A_7(GammaInv,0);CHKERRQ(ierr); break;
24161692a83SJed Brown   default: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented for %D stages",s);
24261692a83SJed Brown   }
24361692a83SJed Brown   for (i=0; i<s*s; i++) t->GammaInv[i] = PetscRealPart(GammaInv[i]);
24461692a83SJed Brown   ierr = PetscFree(GammaInv);CHKERRQ(ierr);
24561692a83SJed Brown   for (i=0; i<s; i++) {
24661692a83SJed Brown     for (j=0; j<s; j++) {
24761692a83SJed Brown       t->At[i*s+j] = 0;
24861692a83SJed Brown       for (k=0; k<s; k++) {
24961692a83SJed Brown         t->At[i*s+j] += t->A[i*s+k] * t->GammaInv[k*s+j];
25061692a83SJed Brown       }
25161692a83SJed Brown     }
25261692a83SJed Brown     t->bt[i] = 0;
25361692a83SJed Brown     for (j=0; j<s; j++) {
25461692a83SJed Brown       t->bt[i] += t->b[j] * t->GammaInv[j*s+i];
25561692a83SJed Brown     }
25661692a83SJed Brown   }
25761692a83SJed Brown   link->next = RosWTableauList;
25861692a83SJed Brown   RosWTableauList = link;
259e27a552bSJed Brown   PetscFunctionReturn(0);
260e27a552bSJed Brown }
261e27a552bSJed Brown 
262e27a552bSJed Brown #undef __FUNCT__
263e27a552bSJed Brown #define __FUNCT__ "TSStep_RosW"
264e27a552bSJed Brown static PetscErrorCode TSStep_RosW(TS ts)
265e27a552bSJed Brown {
26661692a83SJed Brown   TS_RosW         *ros = (TS_RosW*)ts->data;
26761692a83SJed Brown   RosWTableau     tab  = ros->tableau;
268e27a552bSJed Brown   const PetscInt  s    = tab->s;
26961692a83SJed Brown   const PetscReal *At  = tab->At,*Gamma = tab->Gamma,*bt = tab->bt,*ASum = tab->ASum,*GammaInv = tab->GammaInv;
27061692a83SJed Brown   PetscScalar     *w   = ros->work;
27161692a83SJed Brown   Vec             *Y   = ros->Y,Zdot = ros->Zdot,Zstage = ros->Zstage;
272e27a552bSJed Brown   SNES            snes;
273e27a552bSJed Brown   PetscInt        i,j,its,lits;
274cdbf8f93SLisandro Dalcin   PetscReal       next_time_step;
275e27a552bSJed Brown   PetscReal       h,t;
276e27a552bSJed Brown   PetscErrorCode  ierr;
277e27a552bSJed Brown 
278e27a552bSJed Brown   PetscFunctionBegin;
279e27a552bSJed Brown   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
280cdbf8f93SLisandro Dalcin   next_time_step = ts->time_step;
281cdbf8f93SLisandro Dalcin   h = ts->time_step;
282e27a552bSJed Brown   t = ts->ptime;
283e27a552bSJed Brown 
284e27a552bSJed Brown   for (i=0; i<s; i++) {
28561692a83SJed Brown     ros->stage_time = t + h*ASum[i];
28661692a83SJed Brown     ros->shift = 1./(h*Gamma[i*s+i]);
28761692a83SJed Brown 
28861692a83SJed Brown     ierr = VecCopy(ts->vec_sol,Zstage);CHKERRQ(ierr);
28961692a83SJed Brown     ierr = VecMAXPY(Zstage,i,&At[i*s+0],Y);CHKERRQ(ierr);
29061692a83SJed Brown 
29161692a83SJed Brown     for (j=0; j<i; j++) w[j] = 1./h * GammaInv[i*s+j];
29261692a83SJed Brown     ierr = VecZeroEntries(Zdot);CHKERRQ(ierr);
29361692a83SJed Brown     ierr = VecMAXPY(Zdot,i,w,Y);CHKERRQ(ierr);
29461692a83SJed Brown 
295e27a552bSJed Brown     /* Initial guess taken from last stage */
29661692a83SJed Brown     ierr = VecZeroEntries(Y[i]);CHKERRQ(ierr);
29761692a83SJed Brown 
29861692a83SJed Brown     if (!ros->recompute_jacobian && !i) {
29961692a83SJed Brown       ierr = SNESSetLagJacobian(snes,-2);CHKERRQ(ierr); /* Recompute the Jacobian on this solve, but not again */
30061692a83SJed Brown     }
30161692a83SJed Brown 
30261692a83SJed Brown     ierr = SNESSolve(snes,PETSC_NULL,Y[i]);CHKERRQ(ierr);
303e27a552bSJed Brown     ierr = SNESGetIterationNumber(snes,&its);CHKERRQ(ierr);
304e27a552bSJed Brown     ierr = SNESGetLinearSolveIterations(snes,&lits);CHKERRQ(ierr);
305e27a552bSJed Brown     ts->nonlinear_its += its; ts->linear_its += lits;
306e27a552bSJed Brown   }
30761692a83SJed Brown   ierr = VecMAXPY(ts->vec_sol,s,bt,Y);CHKERRQ(ierr);
308e27a552bSJed Brown 
309e27a552bSJed Brown   ts->ptime += ts->time_step;
310cdbf8f93SLisandro Dalcin   ts->time_step = next_time_step;
311e27a552bSJed Brown   ts->steps++;
312e27a552bSJed Brown   PetscFunctionReturn(0);
313e27a552bSJed Brown }
314e27a552bSJed Brown 
315e27a552bSJed Brown #undef __FUNCT__
316e27a552bSJed Brown #define __FUNCT__ "TSInterpolate_RosW"
317e27a552bSJed Brown static PetscErrorCode TSInterpolate_RosW(TS ts,PetscReal itime,Vec X)
318e27a552bSJed Brown {
31961692a83SJed Brown   TS_RosW        *ros = (TS_RosW*)ts->data;
320e27a552bSJed Brown 
321e27a552bSJed Brown   PetscFunctionBegin;
32261692a83SJed Brown   SETERRQ1(((PetscObject)ts)->comm,PETSC_ERR_SUP,"TSRosW %s does not have an interpolation formula",ros->tableau->name);
323e27a552bSJed Brown   PetscFunctionReturn(0);
324e27a552bSJed Brown }
325e27a552bSJed Brown 
326e27a552bSJed Brown /*------------------------------------------------------------*/
327e27a552bSJed Brown #undef __FUNCT__
328e27a552bSJed Brown #define __FUNCT__ "TSReset_RosW"
329e27a552bSJed Brown static PetscErrorCode TSReset_RosW(TS ts)
330e27a552bSJed Brown {
33161692a83SJed Brown   TS_RosW        *ros = (TS_RosW*)ts->data;
332e27a552bSJed Brown   PetscInt       s;
333e27a552bSJed Brown   PetscErrorCode ierr;
334e27a552bSJed Brown 
335e27a552bSJed Brown   PetscFunctionBegin;
33661692a83SJed Brown   if (!ros->tableau) PetscFunctionReturn(0);
33761692a83SJed Brown    s = ros->tableau->s;
33861692a83SJed Brown   ierr = VecDestroyVecs(s,&ros->Y);CHKERRQ(ierr);
33961692a83SJed Brown   ierr = VecDestroy(&ros->Ydot);CHKERRQ(ierr);
34061692a83SJed Brown   ierr = VecDestroy(&ros->Ystage);CHKERRQ(ierr);
34161692a83SJed Brown   ierr = VecDestroy(&ros->Zdot);CHKERRQ(ierr);
34261692a83SJed Brown   ierr = VecDestroy(&ros->Zstage);CHKERRQ(ierr);
34361692a83SJed Brown   ierr = PetscFree(ros->work);CHKERRQ(ierr);
344e27a552bSJed Brown   PetscFunctionReturn(0);
345e27a552bSJed Brown }
346e27a552bSJed Brown 
347e27a552bSJed Brown #undef __FUNCT__
348e27a552bSJed Brown #define __FUNCT__ "TSDestroy_RosW"
349e27a552bSJed Brown static PetscErrorCode TSDestroy_RosW(TS ts)
350e27a552bSJed Brown {
351e27a552bSJed Brown   PetscErrorCode  ierr;
352e27a552bSJed Brown 
353e27a552bSJed Brown   PetscFunctionBegin;
354e27a552bSJed Brown   ierr = TSReset_RosW(ts);CHKERRQ(ierr);
355e27a552bSJed Brown   ierr = PetscFree(ts->data);CHKERRQ(ierr);
356e27a552bSJed Brown   ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSRosWGetType_C","",PETSC_NULL);CHKERRQ(ierr);
357e27a552bSJed Brown   ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSRosWSetType_C","",PETSC_NULL);CHKERRQ(ierr);
35861692a83SJed Brown   ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSRosWSetRecomputeJacobian_C","",PETSC_NULL);CHKERRQ(ierr);
359e27a552bSJed Brown   PetscFunctionReturn(0);
360e27a552bSJed Brown }
361e27a552bSJed Brown 
362e27a552bSJed Brown /*
363e27a552bSJed Brown   This defines the nonlinear equation that is to be solved with SNES
364e27a552bSJed Brown   G(U) = F[t0+Theta*dt, U, (U-U0)*shift] = 0
365e27a552bSJed Brown */
366e27a552bSJed Brown #undef __FUNCT__
367e27a552bSJed Brown #define __FUNCT__ "SNESTSFormFunction_RosW"
368e27a552bSJed Brown static PetscErrorCode SNESTSFormFunction_RosW(SNES snes,Vec X,Vec F,TS ts)
369e27a552bSJed Brown {
37061692a83SJed Brown   TS_RosW        *ros = (TS_RosW*)ts->data;
371e27a552bSJed Brown   PetscErrorCode ierr;
372e27a552bSJed Brown 
373e27a552bSJed Brown   PetscFunctionBegin;
37461692a83SJed Brown   ierr = VecWAXPY(ros->Ydot,ros->shift,X,ros->Zdot);CHKERRQ(ierr); /* Ydot = shift*X + Zdot */
37561692a83SJed Brown   ierr = VecWAXPY(ros->Ystage,1.0,X,ros->Zstage);CHKERRQ(ierr);    /* Ystage = X + Zstage */
37661692a83SJed Brown   ierr = TSComputeIFunction(ts,ros->stage_time,ros->Ystage,ros->Ydot,F,PETSC_FALSE);CHKERRQ(ierr);
377e27a552bSJed Brown   PetscFunctionReturn(0);
378e27a552bSJed Brown }
379e27a552bSJed Brown 
380e27a552bSJed Brown #undef __FUNCT__
381e27a552bSJed Brown #define __FUNCT__ "SNESTSFormJacobian_RosW"
382e27a552bSJed Brown static PetscErrorCode SNESTSFormJacobian_RosW(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *str,TS ts)
383e27a552bSJed Brown {
38461692a83SJed Brown   TS_RosW        *ros = (TS_RosW*)ts->data;
385e27a552bSJed Brown   PetscErrorCode ierr;
386e27a552bSJed Brown 
387e27a552bSJed Brown   PetscFunctionBegin;
38861692a83SJed Brown   /* ros->Ydot and ros->Ystage have already been computed in SNESTSFormFunction_RosW (SNES guarantees this) */
38961692a83SJed Brown   ierr = TSComputeIJacobian(ts,ros->stage_time,ros->Ystage,ros->Ydot,ros->shift,A,B,str,PETSC_TRUE);CHKERRQ(ierr);
390e27a552bSJed Brown   PetscFunctionReturn(0);
391e27a552bSJed Brown }
392e27a552bSJed Brown 
393e27a552bSJed Brown #undef __FUNCT__
394e27a552bSJed Brown #define __FUNCT__ "TSSetUp_RosW"
395e27a552bSJed Brown static PetscErrorCode TSSetUp_RosW(TS ts)
396e27a552bSJed Brown {
39761692a83SJed Brown   TS_RosW        *ros = (TS_RosW*)ts->data;
39861692a83SJed Brown   RosWTableau    tab  = ros->tableau;
399e27a552bSJed Brown   PetscInt       s    = tab->s;
400e27a552bSJed Brown   PetscErrorCode ierr;
401e27a552bSJed Brown 
402e27a552bSJed Brown   PetscFunctionBegin;
40361692a83SJed Brown   if (!ros->tableau) {
404e27a552bSJed Brown     ierr = TSRosWSetType(ts,TSRosWDefault);CHKERRQ(ierr);
405e27a552bSJed Brown   }
40661692a83SJed Brown   ierr = VecDuplicateVecs(ts->vec_sol,s,&ros->Y);CHKERRQ(ierr);
40761692a83SJed Brown   ierr = VecDuplicate(ts->vec_sol,&ros->Ydot);CHKERRQ(ierr);
40861692a83SJed Brown   ierr = VecDuplicate(ts->vec_sol,&ros->Ystage);CHKERRQ(ierr);
40961692a83SJed Brown   ierr = VecDuplicate(ts->vec_sol,&ros->Zdot);CHKERRQ(ierr);
41061692a83SJed Brown   ierr = VecDuplicate(ts->vec_sol,&ros->Zstage);CHKERRQ(ierr);
41161692a83SJed Brown   ierr = PetscMalloc(s*sizeof(ros->work[0]),&ros->work);CHKERRQ(ierr);
412e27a552bSJed Brown   PetscFunctionReturn(0);
413e27a552bSJed Brown }
414e27a552bSJed Brown /*------------------------------------------------------------*/
415e27a552bSJed Brown 
416e27a552bSJed Brown #undef __FUNCT__
417e27a552bSJed Brown #define __FUNCT__ "TSSetFromOptions_RosW"
418e27a552bSJed Brown static PetscErrorCode TSSetFromOptions_RosW(TS ts)
419e27a552bSJed Brown {
42061692a83SJed Brown   TS_RosW        *ros = (TS_RosW*)ts->data;
421e27a552bSJed Brown   PetscErrorCode ierr;
42261692a83SJed Brown   char           rostype[256];
423e27a552bSJed Brown 
424e27a552bSJed Brown   PetscFunctionBegin;
425e27a552bSJed Brown   ierr = PetscOptionsHead("RosW ODE solver options");CHKERRQ(ierr);
426e27a552bSJed Brown   {
42761692a83SJed Brown     RosWTableauLink link;
428e27a552bSJed Brown     PetscInt count,choice;
429e27a552bSJed Brown     PetscBool flg;
430e27a552bSJed Brown     const char **namelist;
43161692a83SJed Brown     SNES snes;
43261692a83SJed Brown 
43361692a83SJed Brown     ierr = PetscStrncpy(rostype,TSRosWDefault,sizeof rostype);CHKERRQ(ierr);
43461692a83SJed Brown     for (link=RosWTableauList,count=0; link; link=link->next,count++) ;
435e27a552bSJed Brown     ierr = PetscMalloc(count*sizeof(char*),&namelist);CHKERRQ(ierr);
43661692a83SJed Brown     for (link=RosWTableauList,count=0; link; link=link->next,count++) namelist[count] = link->tab.name;
43761692a83SJed Brown     ierr = PetscOptionsEList("-ts_rosw_type","Family of Rosenbrock-W method","TSRosWSetType",(const char*const*)namelist,count,rostype,&choice,&flg);CHKERRQ(ierr);
43861692a83SJed Brown     ierr = TSRosWSetType(ts,flg ? namelist[choice] : rostype);CHKERRQ(ierr);
439e27a552bSJed Brown     ierr = PetscFree(namelist);CHKERRQ(ierr);
44061692a83SJed Brown 
44161692a83SJed Brown     ierr = PetscOptionsBool("-ts_rosw_recompute_jacobian","Recompute the Jacobian at each stage","TSRosWSetRecomputeJacobian",ros->recompute_jacobian,&ros->recompute_jacobian,PETSC_NULL);CHKERRQ(ierr);
44261692a83SJed Brown 
44361692a83SJed Brown     /* Rosenbrock methods are linearly implicit, so set that unless the user has specifically asked for something else */
44461692a83SJed Brown     ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
44561692a83SJed Brown     if (!((PetscObject)snes)->type_name) {
44661692a83SJed Brown       ierr = SNESSetType(snes,SNESKSPONLY);CHKERRQ(ierr);
44761692a83SJed Brown     }
44861692a83SJed Brown     ierr = SNESSetFromOptions(snes);CHKERRQ(ierr);
449e27a552bSJed Brown   }
450e27a552bSJed Brown   ierr = PetscOptionsTail();CHKERRQ(ierr);
451e27a552bSJed Brown   PetscFunctionReturn(0);
452e27a552bSJed Brown }
453e27a552bSJed Brown 
454e27a552bSJed Brown #undef __FUNCT__
455e27a552bSJed Brown #define __FUNCT__ "PetscFormatRealArray"
456e27a552bSJed Brown static PetscErrorCode PetscFormatRealArray(char buf[],size_t len,const char *fmt,PetscInt n,const PetscReal x[])
457e27a552bSJed Brown {
458e27a552bSJed Brown   PetscErrorCode ierr;
459*e408995aSJed Brown   PetscInt i;
460*e408995aSJed Brown   size_t left,count;
461e27a552bSJed Brown   char *p;
462e27a552bSJed Brown 
463e27a552bSJed Brown   PetscFunctionBegin;
464*e408995aSJed Brown   for (i=0,p=buf,left=len; i<n; i++) {
465*e408995aSJed Brown     ierr = PetscSNPrintfCount(p,left,fmt,&count,x[i]);CHKERRQ(ierr);
466e27a552bSJed Brown     if (count >= left) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Insufficient space in buffer");
467e27a552bSJed Brown     left -= count;
468e27a552bSJed Brown     p += count;
469e27a552bSJed Brown     *p++ = ' ';
470e27a552bSJed Brown   }
471e27a552bSJed Brown   p[i ? 0 : -1] = 0;
472e27a552bSJed Brown   PetscFunctionReturn(0);
473e27a552bSJed Brown }
474e27a552bSJed Brown 
475e27a552bSJed Brown #undef __FUNCT__
476e27a552bSJed Brown #define __FUNCT__ "TSView_RosW"
477e27a552bSJed Brown static PetscErrorCode TSView_RosW(TS ts,PetscViewer viewer)
478e27a552bSJed Brown {
47961692a83SJed Brown   TS_RosW        *ros = (TS_RosW*)ts->data;
48061692a83SJed Brown   RosWTableau    tab  = ros->tableau;
481e27a552bSJed Brown   PetscBool      iascii;
482e27a552bSJed Brown   PetscErrorCode ierr;
483e27a552bSJed Brown 
484e27a552bSJed Brown   PetscFunctionBegin;
485e27a552bSJed Brown   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
486e27a552bSJed Brown   if (iascii) {
48761692a83SJed Brown     const TSRosWType rostype;
488*e408995aSJed Brown     PetscInt i;
489*e408995aSJed Brown     PetscReal abscissa[512];
490e27a552bSJed Brown     char buf[512];
49161692a83SJed Brown     ierr = TSRosWGetType(ts,&rostype);CHKERRQ(ierr);
49261692a83SJed Brown     ierr = PetscViewerASCIIPrintf(viewer,"  Rosenbrock-W %s\n",rostype);CHKERRQ(ierr);
493*e408995aSJed Brown     ierr = PetscFormatRealArray(buf,sizeof buf,"% 8.6f",tab->s,tab->ASum);CHKERRQ(ierr);
49461692a83SJed Brown     ierr = PetscViewerASCIIPrintf(viewer,"  Abscissa of A       = %s\n",buf);CHKERRQ(ierr);
495*e408995aSJed Brown     for (i=0; i<tab->s; i++) abscissa[i] = tab->ASum[i] + tab->Gamma[i];
496*e408995aSJed Brown     ierr = PetscFormatRealArray(buf,sizeof buf,"% 8.6f",tab->s,abscissa);CHKERRQ(ierr);
497*e408995aSJed Brown     ierr = PetscViewerASCIIPrintf(viewer,"  Abscissa of A+Gamma = %s\n",buf);CHKERRQ(ierr);
498e27a552bSJed Brown   }
499e27a552bSJed Brown   ierr = SNESView(ts->snes,viewer);CHKERRQ(ierr);
500e27a552bSJed Brown   PetscFunctionReturn(0);
501e27a552bSJed Brown }
502e27a552bSJed Brown 
503e27a552bSJed Brown #undef __FUNCT__
504e27a552bSJed Brown #define __FUNCT__ "TSRosWSetType"
505e27a552bSJed Brown /*@C
50661692a83SJed Brown   TSRosWSetType - Set the type of Rosenbrock-W scheme
507e27a552bSJed Brown 
508e27a552bSJed Brown   Logically collective
509e27a552bSJed Brown 
510e27a552bSJed Brown   Input Parameter:
511e27a552bSJed Brown +  ts - timestepping context
51261692a83SJed Brown -  rostype - type of Rosenbrock-W scheme
513e27a552bSJed Brown 
514e27a552bSJed Brown   Level: intermediate
515e27a552bSJed Brown 
516e27a552bSJed Brown .seealso: TSRosWGetType()
517e27a552bSJed Brown @*/
51861692a83SJed Brown PetscErrorCode TSRosWSetType(TS ts,const TSRosWType rostype)
519e27a552bSJed Brown {
520e27a552bSJed Brown   PetscErrorCode ierr;
521e27a552bSJed Brown 
522e27a552bSJed Brown   PetscFunctionBegin;
523e27a552bSJed Brown   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
52461692a83SJed Brown   ierr = PetscTryMethod(ts,"TSRosWSetType_C",(TS,const TSRosWType),(ts,rostype));CHKERRQ(ierr);
525e27a552bSJed Brown   PetscFunctionReturn(0);
526e27a552bSJed Brown }
527e27a552bSJed Brown 
528e27a552bSJed Brown #undef __FUNCT__
529e27a552bSJed Brown #define __FUNCT__ "TSRosWGetType"
530e27a552bSJed Brown /*@C
53161692a83SJed Brown   TSRosWGetType - Get the type of Rosenbrock-W scheme
532e27a552bSJed Brown 
533e27a552bSJed Brown   Logically collective
534e27a552bSJed Brown 
535e27a552bSJed Brown   Input Parameter:
536e27a552bSJed Brown .  ts - timestepping context
537e27a552bSJed Brown 
538e27a552bSJed Brown   Output Parameter:
53961692a83SJed Brown .  rostype - type of Rosenbrock-W scheme
540e27a552bSJed Brown 
541e27a552bSJed Brown   Level: intermediate
542e27a552bSJed Brown 
543e27a552bSJed Brown .seealso: TSRosWGetType()
544e27a552bSJed Brown @*/
54561692a83SJed Brown PetscErrorCode TSRosWGetType(TS ts,const TSRosWType *rostype)
546e27a552bSJed Brown {
547e27a552bSJed Brown   PetscErrorCode ierr;
548e27a552bSJed Brown 
549e27a552bSJed Brown   PetscFunctionBegin;
550e27a552bSJed Brown   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
55161692a83SJed Brown   ierr = PetscUseMethod(ts,"TSRosWGetType_C",(TS,const TSRosWType*),(ts,rostype));CHKERRQ(ierr);
552e27a552bSJed Brown   PetscFunctionReturn(0);
553e27a552bSJed Brown }
554e27a552bSJed Brown 
555e27a552bSJed Brown #undef __FUNCT__
55661692a83SJed Brown #define __FUNCT__ "TSRosWSetRecomputeJacobian"
557e27a552bSJed Brown /*@C
55861692a83SJed Brown   TSRosWSetRecomputeJacobian - Set whether to recompute the Jacobian at each stage. The default is to update the Jacobian once per step.
559e27a552bSJed Brown 
560e27a552bSJed Brown   Logically collective
561e27a552bSJed Brown 
562e27a552bSJed Brown   Input Parameter:
563e27a552bSJed Brown +  ts - timestepping context
56461692a83SJed Brown -  flg - PETSC_TRUE to recompute the Jacobian at each stage
565e27a552bSJed Brown 
566e27a552bSJed Brown   Level: intermediate
567e27a552bSJed Brown 
568e27a552bSJed Brown .seealso: TSRosWGetType()
569e27a552bSJed Brown @*/
57061692a83SJed Brown PetscErrorCode TSRosWSetRecomputeJacobian(TS ts,PetscBool flg)
571e27a552bSJed Brown {
572e27a552bSJed Brown   PetscErrorCode ierr;
573e27a552bSJed Brown 
574e27a552bSJed Brown   PetscFunctionBegin;
575e27a552bSJed Brown   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
57661692a83SJed Brown   ierr = PetscTryMethod(ts,"TSRosWSetRecomputeJacobian_C",(TS,PetscBool),(ts,flg));CHKERRQ(ierr);
577e27a552bSJed Brown   PetscFunctionReturn(0);
578e27a552bSJed Brown }
579e27a552bSJed Brown 
580e27a552bSJed Brown EXTERN_C_BEGIN
581e27a552bSJed Brown #undef __FUNCT__
582e27a552bSJed Brown #define __FUNCT__ "TSRosWGetType_RosW"
58361692a83SJed Brown PetscErrorCode  TSRosWGetType_RosW(TS ts,const TSRosWType *rostype)
584e27a552bSJed Brown {
58561692a83SJed Brown   TS_RosW        *ros = (TS_RosW*)ts->data;
586e27a552bSJed Brown   PetscErrorCode ierr;
587e27a552bSJed Brown 
588e27a552bSJed Brown   PetscFunctionBegin;
58961692a83SJed Brown   if (!ros->tableau) {ierr = TSRosWSetType(ts,TSRosWDefault);CHKERRQ(ierr);}
59061692a83SJed Brown   *rostype = ros->tableau->name;
591e27a552bSJed Brown   PetscFunctionReturn(0);
592e27a552bSJed Brown }
593e27a552bSJed Brown #undef __FUNCT__
594e27a552bSJed Brown #define __FUNCT__ "TSRosWSetType_RosW"
59561692a83SJed Brown PetscErrorCode  TSRosWSetType_RosW(TS ts,const TSRosWType rostype)
596e27a552bSJed Brown {
59761692a83SJed Brown   TS_RosW         *ros = (TS_RosW*)ts->data;
598e27a552bSJed Brown   PetscErrorCode  ierr;
599e27a552bSJed Brown   PetscBool       match;
60061692a83SJed Brown   RosWTableauLink link;
601e27a552bSJed Brown 
602e27a552bSJed Brown   PetscFunctionBegin;
60361692a83SJed Brown   if (ros->tableau) {
60461692a83SJed Brown     ierr = PetscStrcmp(ros->tableau->name,rostype,&match);CHKERRQ(ierr);
605e27a552bSJed Brown     if (match) PetscFunctionReturn(0);
606e27a552bSJed Brown   }
60761692a83SJed Brown   for (link = RosWTableauList; link; link=link->next) {
60861692a83SJed Brown     ierr = PetscStrcmp(link->tab.name,rostype,&match);CHKERRQ(ierr);
609e27a552bSJed Brown     if (match) {
610e27a552bSJed Brown       ierr = TSReset_RosW(ts);CHKERRQ(ierr);
61161692a83SJed Brown       ros->tableau = &link->tab;
612e27a552bSJed Brown       PetscFunctionReturn(0);
613e27a552bSJed Brown     }
614e27a552bSJed Brown   }
61561692a83SJed Brown   SETERRQ1(((PetscObject)ts)->comm,PETSC_ERR_ARG_UNKNOWN_TYPE,"Could not find '%s'",rostype);
616e27a552bSJed Brown   PetscFunctionReturn(0);
617e27a552bSJed Brown }
61861692a83SJed Brown 
619e27a552bSJed Brown #undef __FUNCT__
62061692a83SJed Brown #define __FUNCT__ "TSRosWSetRecomputeJacobian_RosW"
62161692a83SJed Brown PetscErrorCode  TSRosWSetRecomputeJacobian_RosW(TS ts,PetscBool flg)
622e27a552bSJed Brown {
62361692a83SJed Brown   TS_RosW *ros = (TS_RosW*)ts->data;
624e27a552bSJed Brown 
625e27a552bSJed Brown   PetscFunctionBegin;
62661692a83SJed Brown   ros->recompute_jacobian = flg;
627e27a552bSJed Brown   PetscFunctionReturn(0);
628e27a552bSJed Brown }
629e27a552bSJed Brown EXTERN_C_END
630e27a552bSJed Brown 
631e27a552bSJed Brown /* ------------------------------------------------------------ */
632e27a552bSJed Brown /*MC
633e27a552bSJed Brown       TSRosW - ODE solver using Rosenbrock-W schemes
634e27a552bSJed Brown 
635e27a552bSJed Brown   These methods are intended for problems with well-separated time scales, especially when a slow scale is strongly
636e27a552bSJed Brown   nonlinear such that it is expensive to solve with a fully implicit method. The user should provide the stiff part
637e27a552bSJed Brown   of the equation using TSSetIFunction() and the non-stiff part with TSSetRHSFunction().
638e27a552bSJed Brown 
639e27a552bSJed Brown   Notes:
64061692a83SJed Brown   This method currently only works with autonomous ODE and DAE.
64161692a83SJed Brown 
64261692a83SJed Brown   Developer notes:
64361692a83SJed Brown   Rosenbrock-W methods are typically specified for autonomous ODE
64461692a83SJed Brown 
64561692a83SJed Brown $  xdot = f(x)
64661692a83SJed Brown 
64761692a83SJed Brown   by the stage equations
64861692a83SJed Brown 
64961692a83SJed Brown $  k_i = h f(x_0 + sum_j alpha_ij k_j) + h J sum_j gamma_ij k_j
65061692a83SJed Brown 
65161692a83SJed Brown   and step completion formula
65261692a83SJed Brown 
65361692a83SJed Brown $  x_1 = x_0 + sum_j b_j k_j
65461692a83SJed Brown 
65561692a83SJed Brown   with step size h and coefficients alpha_ij, gamma_ij, and b_i. Implementing the method in this form would require f(x)
65661692a83SJed Brown   and the Jacobian J to be available, in addition to the shifted matrix I - h gamma_ii J. Following Hairer and Wanner,
65761692a83SJed Brown   we define new variables for the stage equations
65861692a83SJed Brown 
65961692a83SJed Brown $  y_i = gamma_ij k_j
66061692a83SJed Brown 
66161692a83SJed Brown   The k_j can be recovered because Gamma is invertible. Let C be the lower triangular part of Gamma^{-1} and define
66261692a83SJed Brown 
66361692a83SJed Brown $  A = Alpha Gamma^{-1}, bt^T = b^T Gamma^{-i}
66461692a83SJed Brown 
66561692a83SJed Brown   to rewrite the method as
66661692a83SJed Brown 
66761692a83SJed 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
66861692a83SJed Brown $  x_1 = x_0 + sum_j bt_j y_j
66961692a83SJed Brown 
67061692a83SJed Brown    where we have introduced the mass matrix M. Continue by defining
67161692a83SJed Brown 
67261692a83SJed Brown $  ydot_i = 1/(h gamma_ii) y_i - sum_j (c_ij/h) y_j
67361692a83SJed Brown 
67461692a83SJed Brown    or, more compactly in tensor notation
67561692a83SJed Brown 
67661692a83SJed Brown $  Ydot = 1/h (Gamma^{-1} \otimes I) Y .
67761692a83SJed Brown 
67861692a83SJed Brown    Note that Gamma^{-1} is lower triangular. With this definition of Ydot in terms of known quantities and the current
67961692a83SJed Brown    stage y_i, the stage equations reduce to performing one Newton step (typically with a lagged Jacobian) on the
68061692a83SJed Brown    equation
68161692a83SJed Brown 
68261692a83SJed Brown $  g(x_0 + sum_j a_ij y_j + y_i, ydot_i) = 0
68361692a83SJed Brown 
68461692a83SJed Brown    with initial guess y_i = 0.
685e27a552bSJed Brown 
686e27a552bSJed Brown   Level: beginner
687e27a552bSJed Brown 
688e27a552bSJed Brown .seealso:  TSCreate(), TS, TSSetType(), TSRosWRegister()
689e27a552bSJed Brown 
690e27a552bSJed Brown M*/
691e27a552bSJed Brown EXTERN_C_BEGIN
692e27a552bSJed Brown #undef __FUNCT__
693e27a552bSJed Brown #define __FUNCT__ "TSCreate_RosW"
694e27a552bSJed Brown PetscErrorCode  TSCreate_RosW(TS ts)
695e27a552bSJed Brown {
69661692a83SJed Brown   TS_RosW        *ros;
697e27a552bSJed Brown   PetscErrorCode ierr;
698e27a552bSJed Brown 
699e27a552bSJed Brown   PetscFunctionBegin;
700e27a552bSJed Brown #if !defined(PETSC_USE_DYNAMIC_LIBRARIES)
701e27a552bSJed Brown   ierr = TSRosWInitializePackage(PETSC_NULL);CHKERRQ(ierr);
702e27a552bSJed Brown #endif
703e27a552bSJed Brown 
704e27a552bSJed Brown   ts->ops->reset          = TSReset_RosW;
705e27a552bSJed Brown   ts->ops->destroy        = TSDestroy_RosW;
706e27a552bSJed Brown   ts->ops->view           = TSView_RosW;
707e27a552bSJed Brown   ts->ops->setup          = TSSetUp_RosW;
708e27a552bSJed Brown   ts->ops->step           = TSStep_RosW;
709e27a552bSJed Brown   ts->ops->interpolate    = TSInterpolate_RosW;
710e27a552bSJed Brown   ts->ops->setfromoptions = TSSetFromOptions_RosW;
711e27a552bSJed Brown   ts->ops->snesfunction   = SNESTSFormFunction_RosW;
712e27a552bSJed Brown   ts->ops->snesjacobian   = SNESTSFormJacobian_RosW;
713e27a552bSJed Brown 
71461692a83SJed Brown   ierr = PetscNewLog(ts,TS_RosW,&ros);CHKERRQ(ierr);
71561692a83SJed Brown   ts->data = (void*)ros;
716e27a552bSJed Brown 
717e27a552bSJed Brown   ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSRosWGetType_C","TSRosWGetType_RosW",TSRosWGetType_RosW);CHKERRQ(ierr);
718e27a552bSJed Brown   ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSRosWSetType_C","TSRosWSetType_RosW",TSRosWSetType_RosW);CHKERRQ(ierr);
71961692a83SJed Brown   ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSRosWSetRecomputeJacobian_C","TSRosWSetRecomputeJacobian_RosW",TSRosWSetRecomputeJacobian_RosW);CHKERRQ(ierr);
720e27a552bSJed Brown   PetscFunctionReturn(0);
721e27a552bSJed Brown }
722e27a552bSJed Brown EXTERN_C_END
723