xref: /petsc/src/ts/impls/rosw/rosw.c (revision cdbf8f939cdfb1c797c4b7f2cbbd00be19935363)
1e27a552bSJed Brown /*
2e27a552bSJed Brown   Code for timestepping with additive Runge-Kutta IMEX method
3e27a552bSJed Brown 
4e27a552bSJed Brown   Notes:
5e27a552bSJed Brown   The general system is written as
6e27a552bSJed Brown 
7e27a552bSJed Brown   F(t,X,Xdot) = G(t,X)
8e27a552bSJed Brown 
9e27a552bSJed Brown   where F represents the stiff part of the physics and G represents the non-stiff part.
10e27a552bSJed Brown 
11e27a552bSJed Brown */
12e27a552bSJed Brown #include <private/tsimpl.h>                /*I   "petscts.h"   I*/
13e27a552bSJed Brown 
14e27a552bSJed Brown static const TSRosWType TSRosWDefault = TSROSW2E;
15e27a552bSJed Brown static PetscBool TSRosWRegisterAllCalled;
16e27a552bSJed Brown static PetscBool TSRosWPackageInitialized;
17e27a552bSJed Brown 
18e27a552bSJed Brown typedef struct _ARKTableau *ARKTableau;
19e27a552bSJed Brown struct _ARKTableau {
20e27a552bSJed Brown   char *name;
21e27a552bSJed Brown   PetscInt order;               /* Classical approximation order of the method */
22e27a552bSJed Brown   PetscInt s;                   /* Number of stages */
23e27a552bSJed Brown   PetscInt pinterp;             /* Interpolation order */
24e27a552bSJed Brown   PetscReal *At,*bt,*ct;        /* Stiff tableau */
25e27a552bSJed Brown   PetscReal *A,*b,*c;           /* Non-stiff tableau */
26e27a552bSJed Brown   PetscReal *binterpt,*binterp; /* Dense output formula */
27e27a552bSJed Brown };
28e27a552bSJed Brown typedef struct _ARKTableauLink *ARKTableauLink;
29e27a552bSJed Brown struct _ARKTableauLink {
30e27a552bSJed Brown   struct _ARKTableau tab;
31e27a552bSJed Brown   ARKTableauLink next;
32e27a552bSJed Brown };
33e27a552bSJed Brown static ARKTableauLink ARKTableauList;
34e27a552bSJed Brown 
35e27a552bSJed Brown typedef struct {
36e27a552bSJed Brown   ARKTableau  tableau;
37e27a552bSJed Brown   Vec         *Y;               /* States computed during the step */
38e27a552bSJed Brown   Vec         *YdotI;           /* Time derivatives for the stiff part */
39e27a552bSJed Brown   Vec         *YdotRHS;         /* Function evaluations for the non-stiff part */
40e27a552bSJed Brown   Vec         Ydot;             /* Work vector holding Ydot during residual evaluation */
41e27a552bSJed Brown   Vec         Work;             /* Generic work vector */
42e27a552bSJed Brown   Vec         Z;                /* Ydot = shift(Y-Z) */
43e27a552bSJed Brown   PetscScalar *work;            /* Scalar work */
44e27a552bSJed Brown   PetscReal   shift;
45e27a552bSJed Brown   PetscReal   stage_time;
46e27a552bSJed Brown   PetscBool   imex;
47e27a552bSJed Brown } TS_RosW;
48e27a552bSJed Brown 
49e27a552bSJed Brown #undef __FUNCT__
50e27a552bSJed Brown #define __FUNCT__ "TSRosWRegisterAll"
51e27a552bSJed Brown /*@C
52e27a552bSJed Brown   TSRosWRegisterAll - Registers all of the additive Runge-Kutta implicit-explicit methods in TSRosW
53e27a552bSJed Brown 
54e27a552bSJed Brown   Not Collective, but should be called by all processes which will need the schemes to be registered
55e27a552bSJed Brown 
56e27a552bSJed Brown   Level: advanced
57e27a552bSJed Brown 
58e27a552bSJed Brown .keywords: TS, TSRosW, register, all
59e27a552bSJed Brown 
60e27a552bSJed Brown .seealso:  TSRosWRegisterDestroy()
61e27a552bSJed Brown @*/
62e27a552bSJed Brown PetscErrorCode TSRosWRegisterAll(void)
63e27a552bSJed Brown {
64e27a552bSJed Brown   PetscErrorCode ierr;
65e27a552bSJed Brown 
66e27a552bSJed Brown   PetscFunctionBegin;
67e27a552bSJed Brown   if (TSRosWRegisterAllCalled) PetscFunctionReturn(0);
68e27a552bSJed Brown   TSRosWRegisterAllCalled = PETSC_TRUE;
69e27a552bSJed Brown 
70e27a552bSJed Brown   {
71e27a552bSJed Brown     const PetscReal
72e27a552bSJed Brown       A[3][3] = {{0,0,0},
73e27a552bSJed Brown                  {0.41421356237309504880,0,0},
74e27a552bSJed Brown                  {0.75,0.25,0}},
75e27a552bSJed Brown       At[3][3] = {{0,0,0},
76e27a552bSJed Brown                   {0.12132034355964257320,0.29289321881345247560,0},
77e27a552bSJed Brown                   {0.20710678118654752440,0.50000000000000000000,0.29289321881345247560}},
78e27a552bSJed Brown       binterpt[3][2] = {{1,-0.5},{0,0},{0,0.5}};
79e27a552bSJed Brown     ierr = TSRosWRegister(TSROSW2D,2,3,&At[0][0],PETSC_NULL,PETSC_NULL,&A[0][0],PETSC_NULL,PETSC_NULL,2,binterpt[0],PETSC_NULL);CHKERRQ(ierr);
80e27a552bSJed Brown   }
81e27a552bSJed Brown   {                             /* Optimal for linear implicit part */
82e27a552bSJed Brown     const PetscReal s2 = PetscSqrtReal((PetscReal)2.0),
83e27a552bSJed Brown       A[3][3] = {{0,0,0},
84e27a552bSJed Brown                  {2-s2,0,0},
85e27a552bSJed Brown                  {(3-2*s2)/6,(3+2*s2)/6,0}},
86e27a552bSJed Brown       At[3][3] = {{0,0,0},
87e27a552bSJed Brown                   {1-1/s2,1-1/s2,0},
88e27a552bSJed Brown                   {1/(2*s2),1/(2*s2),1-1/s2}},
89e27a552bSJed Brown       binterpt[3][2] = {{1,-0.5},{0,0},{0,0.5}};
90e27a552bSJed Brown     ierr = TSRosWRegister(TSROSW2E,2,3,&At[0][0],PETSC_NULL,PETSC_NULL,&A[0][0],PETSC_NULL,PETSC_NULL,2,binterpt[0],PETSC_NULL);CHKERRQ(ierr);
91e27a552bSJed Brown   }
92e27a552bSJed Brown   {
93e27a552bSJed Brown     const PetscReal
94e27a552bSJed Brown       A[4][4] = {{0,0,0,0},
95e27a552bSJed Brown                  {1767732205903./2027836641118.,0,0,0},
96e27a552bSJed Brown                  {5535828885825./10492691773637.,788022342437./10882634858940.,0,0},
97e27a552bSJed Brown                  {6485989280629./16251701735622.,-4246266847089./9704473918619.,10755448449292./10357097424841.,0}},
98e27a552bSJed Brown       At[4][4] = {{0,0,0,0},
99e27a552bSJed Brown                   {1767732205903./4055673282236.,1767732205903./4055673282236.,0,0},
100e27a552bSJed Brown                   {2746238789719./10658868560708.,-640167445237./6845629431997.,1767732205903./4055673282236.,0},
101e27a552bSJed Brown                   {1471266399579./7840856788654.,-4482444167858./7529755066697.,11266239266428./11593286722821.,1767732205903./4055673282236.}},
102e27a552bSJed Brown       binterpt[4][2] = {{4655552711362./22874653954995., -215264564351./13552729205753.},
103e27a552bSJed Brown                         {-18682724506714./9892148508045.,17870216137069./13817060693119.},
104e27a552bSJed Brown                         {34259539580243./13192909600954.,-28141676662227./17317692491321.},
105e27a552bSJed Brown                         {584795268549./6622622206610.,   2508943948391./7218656332882.}};
106e27a552bSJed Brown     ierr = TSRosWRegister(TSROSW3,3,4,&At[0][0],PETSC_NULL,PETSC_NULL,&A[0][0],PETSC_NULL,PETSC_NULL,2,binterpt[0],PETSC_NULL);CHKERRQ(ierr);
107e27a552bSJed Brown   }
108e27a552bSJed Brown   {
109e27a552bSJed Brown     const PetscReal
110e27a552bSJed Brown       A[6][6] = {{0,0,0,0,0,0},
111e27a552bSJed Brown                  {1./2,0,0,0,0,0},
112e27a552bSJed Brown                  {13861./62500.,6889./62500.,0,0,0,0},
113e27a552bSJed Brown                  {-116923316275./2393684061468.,-2731218467317./15368042101831.,9408046702089./11113171139209.,0,0,0},
114e27a552bSJed Brown                  {-451086348788./2902428689909.,-2682348792572./7519795681897.,12662868775082./11960479115383.,3355817975965./11060851509271.,0,0},
115e27a552bSJed Brown                  {647845179188./3216320057751.,73281519250./8382639484533.,552539513391./3454668386233.,3354512671639./8306763924573.,4040./17871.,0}},
116e27a552bSJed Brown       At[6][6] = {{0,0,0,0,0,0},
117e27a552bSJed Brown                   {1./4,1./4,0,0,0,0},
118e27a552bSJed Brown                   {8611./62500.,-1743./31250.,1./4,0,0,0},
119e27a552bSJed Brown                   {5012029./34652500.,-654441./2922500.,174375./388108.,1./4,0,0},
120e27a552bSJed Brown                   {15267082809./155376265600.,-71443401./120774400.,730878875./902184768.,2285395./8070912.,1./4,0},
121e27a552bSJed Brown                   {82889./524892.,0,15625./83664.,69875./102672.,-2260./8211,1./4}},
122e27a552bSJed Brown       binterpt[6][3] = {{6943876665148./7220017795957.,-54480133./30881146.,6818779379841./7100303317025.},
123e27a552bSJed Brown                         {0,0,0},
124e27a552bSJed Brown                         {7640104374378./9702883013639.,-11436875./14766696.,2173542590792./12501825683035.},
125e27a552bSJed Brown                         {-20649996744609./7521556579894.,174696575./18121608.,-31592104683404./5083833661969.},
126e27a552bSJed Brown                         {8854892464581./2390941311638.,-12120380./966161.,61146701046299./7138195549469.},
127e27a552bSJed Brown                         {-11397109935349./6675773540249.,3843./706.,-17219254887155./4939391667607.}};
128e27a552bSJed Brown     ierr = TSRosWRegister(TSROSW4,4,6,&At[0][0],PETSC_NULL,PETSC_NULL,&A[0][0],PETSC_NULL,PETSC_NULL,3,binterpt[0],PETSC_NULL);CHKERRQ(ierr);
129e27a552bSJed Brown   }
130e27a552bSJed Brown   {
131e27a552bSJed Brown     const PetscReal
132e27a552bSJed Brown       A[8][8] = {{0,0,0,0,0,0,0,0},
133e27a552bSJed Brown                  {41./100,0,0,0,0,0,0,0},
134e27a552bSJed Brown                  {367902744464./2072280473677.,677623207551./8224143866563.,0,0,0,0,0,0},
135e27a552bSJed Brown                  {1268023523408./10340822734521.,0,1029933939417./13636558850479.,0,0,0,0,0},
136e27a552bSJed Brown                  {14463281900351./6315353703477.,0,66114435211212./5879490589093.,-54053170152839./4284798021562.,0,0,0,0},
137e27a552bSJed Brown                  {14090043504691./34967701212078.,0,15191511035443./11219624916014.,-18461159152457./12425892160975.,-281667163811./9011619295870.,0,0,0},
138e27a552bSJed Brown                  {19230459214898./13134317526959.,0,21275331358303./2942455364971.,-38145345988419./4862620318723.,-1./8,-1./8,0,0},
139e27a552bSJed Brown                  {-19977161125411./11928030595625.,0,-40795976796054./6384907823539.,177454434618887./12078138498510.,782672205425./8267701900261.,-69563011059811./9646580694205.,7356628210526./4942186776405.,0}},
140e27a552bSJed Brown       At[8][8] = {{0,0,0,0,0,0,0,0},
141e27a552bSJed Brown                   {41./200.,41./200.,0,0,0,0,0,0},
142e27a552bSJed Brown                   {41./400.,-567603406766./11931857230679.,41./200.,0,0,0,0,0},
143e27a552bSJed Brown                   {683785636431./9252920307686.,0,-110385047103./1367015193373.,41./200.,0,0,0,0},
144e27a552bSJed Brown                   {3016520224154./10081342136671.,0,30586259806659./12414158314087.,-22760509404356./11113319521817.,41./200.,0,0,0},
145e27a552bSJed Brown                   {218866479029./1489978393911.,0,638256894668./5436446318841.,-1179710474555./5321154724896.,-60928119172./8023461067671.,41./200.,0,0},
146e27a552bSJed Brown                   {1020004230633./5715676835656.,0,25762820946817./25263940353407.,-2161375909145./9755907335909.,-211217309593./5846859502534.,-4269925059573./7827059040749.,41./200,0},
147e27a552bSJed Brown                   {-872700587467./9133579230613.,0,0,22348218063261./9555858737531.,-1143369518992./8141816002931.,-39379526789629./19018526304540.,32727382324388./42900044865799.,41./200.}},
148e27a552bSJed Brown       binterpt[8][3] = {{-17674230611817./10670229744614. ,  43486358583215./12773830924787. , -9257016797708./5021505065439.},
149e27a552bSJed Brown                         {0                               ,  0                              , 0                            },
150e27a552bSJed Brown                         {0                               ,  0                              , 0                            },
151e27a552bSJed Brown                         {65168852399939./7868540260826.  ,  -91478233927265./11067650958493., 26096422576131./11239449250142.},
152e27a552bSJed Brown                         {15494834004392./5936557850923.  ,  -79368583304911./10890268929626., 92396832856987./20362823103730.},
153e27a552bSJed Brown                         {-99329723586156./26959484932159.,  -12239297817655./9152339842473. , 30029262896817./10175596800299.},
154e27a552bSJed Brown                         {-19024464361622./5461577185407. ,  115839755401235./10719374521269., -26136350496073./3983972220547.},
155e27a552bSJed Brown                         {-6511271360970./6095937251113.  ,  5843115559534./2180450260947.   , -5289405421727./3760307252460. }};
156e27a552bSJed Brown     ierr = TSRosWRegister(TSROSW5,5,8,&At[0][0],PETSC_NULL,PETSC_NULL,&A[0][0],PETSC_NULL,PETSC_NULL,3,binterpt[0],PETSC_NULL);CHKERRQ(ierr);
157e27a552bSJed Brown   }
158e27a552bSJed Brown 
159e27a552bSJed Brown   PetscFunctionReturn(0);
160e27a552bSJed Brown }
161e27a552bSJed Brown 
162e27a552bSJed Brown #undef __FUNCT__
163e27a552bSJed Brown #define __FUNCT__ "TSRosWRegisterDestroy"
164e27a552bSJed Brown /*@C
165e27a552bSJed Brown    TSRosWRegisterDestroy - Frees the list of schemes that were registered by TSRosWRegister().
166e27a552bSJed Brown 
167e27a552bSJed Brown    Not Collective
168e27a552bSJed Brown 
169e27a552bSJed Brown    Level: advanced
170e27a552bSJed Brown 
171e27a552bSJed Brown .keywords: TSRosW, register, destroy
172e27a552bSJed Brown .seealso: TSRosWRegister(), TSRosWRegisterAll(), TSRosWRegisterDynamic()
173e27a552bSJed Brown @*/
174e27a552bSJed Brown PetscErrorCode TSRosWRegisterDestroy(void)
175e27a552bSJed Brown {
176e27a552bSJed Brown   PetscErrorCode ierr;
177e27a552bSJed Brown   ARKTableauLink link;
178e27a552bSJed Brown 
179e27a552bSJed Brown   PetscFunctionBegin;
180e27a552bSJed Brown   while ((link = ARKTableauList)) {
181e27a552bSJed Brown     ARKTableau t = &link->tab;
182e27a552bSJed Brown     ARKTableauList = link->next;
183e27a552bSJed Brown     ierr = PetscFree6(t->At,t->bt,t->ct,t->A,t->b,t->c);CHKERRQ(ierr);
184e27a552bSJed Brown     ierr = PetscFree2(t->binterpt,t->binterp);CHKERRQ(ierr);
185e27a552bSJed Brown     ierr = PetscFree(t->name);CHKERRQ(ierr);
186e27a552bSJed Brown     ierr = PetscFree(link);CHKERRQ(ierr);
187e27a552bSJed Brown   }
188e27a552bSJed Brown   TSRosWRegisterAllCalled = PETSC_FALSE;
189e27a552bSJed Brown   PetscFunctionReturn(0);
190e27a552bSJed Brown }
191e27a552bSJed Brown 
192e27a552bSJed Brown #undef __FUNCT__
193e27a552bSJed Brown #define __FUNCT__ "TSRosWInitializePackage"
194e27a552bSJed Brown /*@C
195e27a552bSJed Brown   TSRosWInitializePackage - This function initializes everything in the TSRosW package. It is called
196e27a552bSJed Brown   from PetscDLLibraryRegister() when using dynamic libraries, and on the first call to TSCreate_RosW()
197e27a552bSJed Brown   when using static libraries.
198e27a552bSJed Brown 
199e27a552bSJed Brown   Input Parameter:
200e27a552bSJed Brown   path - The dynamic library path, or PETSC_NULL
201e27a552bSJed Brown 
202e27a552bSJed Brown   Level: developer
203e27a552bSJed Brown 
204e27a552bSJed Brown .keywords: TS, TSRosW, initialize, package
205e27a552bSJed Brown .seealso: PetscInitialize()
206e27a552bSJed Brown @*/
207e27a552bSJed Brown PetscErrorCode TSRosWInitializePackage(const char path[])
208e27a552bSJed Brown {
209e27a552bSJed Brown   PetscErrorCode ierr;
210e27a552bSJed Brown 
211e27a552bSJed Brown   PetscFunctionBegin;
212e27a552bSJed Brown   if (TSRosWPackageInitialized) PetscFunctionReturn(0);
213e27a552bSJed Brown   TSRosWPackageInitialized = PETSC_TRUE;
214e27a552bSJed Brown   ierr = TSRosWRegisterAll();CHKERRQ(ierr);
215e27a552bSJed Brown   ierr = PetscRegisterFinalize(TSRosWFinalizePackage);CHKERRQ(ierr);
216e27a552bSJed Brown   PetscFunctionReturn(0);
217e27a552bSJed Brown }
218e27a552bSJed Brown 
219e27a552bSJed Brown #undef __FUNCT__
220e27a552bSJed Brown #define __FUNCT__ "TSRosWFinalizePackage"
221e27a552bSJed Brown /*@C
222e27a552bSJed Brown   TSRosWFinalizePackage - This function destroys everything in the TSRosW package. It is
223e27a552bSJed Brown   called from PetscFinalize().
224e27a552bSJed Brown 
225e27a552bSJed Brown   Level: developer
226e27a552bSJed Brown 
227e27a552bSJed Brown .keywords: Petsc, destroy, package
228e27a552bSJed Brown .seealso: PetscFinalize()
229e27a552bSJed Brown @*/
230e27a552bSJed Brown PetscErrorCode TSRosWFinalizePackage(void)
231e27a552bSJed Brown {
232e27a552bSJed Brown   PetscErrorCode ierr;
233e27a552bSJed Brown 
234e27a552bSJed Brown   PetscFunctionBegin;
235e27a552bSJed Brown   TSRosWPackageInitialized = PETSC_FALSE;
236e27a552bSJed Brown   ierr = TSRosWRegisterDestroy();CHKERRQ(ierr);
237e27a552bSJed Brown   PetscFunctionReturn(0);
238e27a552bSJed Brown }
239e27a552bSJed Brown 
240e27a552bSJed Brown #undef __FUNCT__
241e27a552bSJed Brown #define __FUNCT__ "TSRosWRegister"
242e27a552bSJed Brown /*@C
243e27a552bSJed Brown    TSRosWRegister - register an ARK IMEX scheme by providing the entries in the Butcher tableau and optionally embedded approximations and interpolation
244e27a552bSJed Brown 
245e27a552bSJed Brown    Not Collective, but the same schemes should be registered on all processes on which they will be used
246e27a552bSJed Brown 
247e27a552bSJed Brown    Input Parameters:
248e27a552bSJed Brown +  name - identifier for method
249e27a552bSJed Brown .  order - approximation order of method
250e27a552bSJed Brown .  s - number of stages, this is the dimension of the matrices below
251e27a552bSJed Brown .  At - Butcher table of stage coefficients for stiff part (dimension s*s, row-major)
252e27a552bSJed Brown .  bt - Butcher table for completing the stiff part of the step (dimension s; PETSC_NULL to use the last row of At)
253e27a552bSJed Brown .  ct - Abscissa of each stiff stage (dimension s, PETSC_NULL to use row sums of At)
254e27a552bSJed Brown .  A - Non-stiff stage coefficients (dimension s*s, row-major)
255e27a552bSJed Brown .  b - Non-stiff step completion table (dimension s; PETSC_NULL to use last row of At)
256e27a552bSJed Brown .  c - Non-stiff abscissa (dimension s; PETSC_NULL to use row sums of A)
257e27a552bSJed Brown .  pinterp - Order of the interpolation scheme, equal to the number of columns of binterpt and binterp
258e27a552bSJed Brown .  binterpt - Coefficients of the interpolation formula for the stiff part (dimension s*pinterp)
259e27a552bSJed Brown -  binterp - Coefficients of the interpolation formula for the non-stiff part (dimension s*pinterp; PETSC_NULL to reuse binterpt)
260e27a552bSJed Brown 
261e27a552bSJed Brown    Notes:
262e27a552bSJed Brown    Several ARK IMEX methods are provided, this function is only needed to create new methods.
263e27a552bSJed Brown 
264e27a552bSJed Brown    Level: advanced
265e27a552bSJed Brown 
266e27a552bSJed Brown .keywords: TS, register
267e27a552bSJed Brown 
268e27a552bSJed Brown .seealso: TSRosW
269e27a552bSJed Brown @*/
270e27a552bSJed Brown PetscErrorCode TSRosWRegister(const TSRosWType name,PetscInt order,PetscInt s,
271e27a552bSJed Brown                                  const PetscReal At[],const PetscReal bt[],const PetscReal ct[],
272e27a552bSJed Brown                                  const PetscReal A[],const PetscReal b[],const PetscReal c[],
273e27a552bSJed Brown                                  PetscInt pinterp,const PetscReal binterpt[],const PetscReal binterp[])
274e27a552bSJed Brown {
275e27a552bSJed Brown   PetscErrorCode ierr;
276e27a552bSJed Brown   ARKTableauLink link;
277e27a552bSJed Brown   ARKTableau t;
278e27a552bSJed Brown   PetscInt i,j;
279e27a552bSJed Brown 
280e27a552bSJed Brown   PetscFunctionBegin;
281e27a552bSJed Brown   ierr = PetscMalloc(sizeof(*link),&link);CHKERRQ(ierr);
282e27a552bSJed Brown   ierr = PetscMemzero(link,sizeof(*link));CHKERRQ(ierr);
283e27a552bSJed Brown   t = &link->tab;
284e27a552bSJed Brown   ierr = PetscStrallocpy(name,&t->name);CHKERRQ(ierr);
285e27a552bSJed Brown   t->order = order;
286e27a552bSJed Brown   t->s = s;
287e27a552bSJed Brown   ierr = PetscMalloc6(s*s,PetscReal,&t->At,s,PetscReal,&t->bt,s,PetscReal,&t->ct,s*s,PetscReal,&t->A,s,PetscReal,&t->b,s,PetscReal,&t->c);CHKERRQ(ierr);
288e27a552bSJed Brown   ierr = PetscMemcpy(t->At,At,s*s*sizeof(At[0]));CHKERRQ(ierr);
289e27a552bSJed Brown   ierr = PetscMemcpy(t->A,A,s*s*sizeof(A[0]));CHKERRQ(ierr);
290e27a552bSJed Brown   if (bt) {ierr = PetscMemcpy(t->bt,bt,s*sizeof(bt[0]));CHKERRQ(ierr);}
291e27a552bSJed Brown   else for (i=0; i<s; i++) t->bt[i] = At[(s-1)*s+i];
292e27a552bSJed Brown   if (b) {ierr = PetscMemcpy(t->b,b,s*sizeof(b[0]));CHKERRQ(ierr);}
293e27a552bSJed Brown   else for (i=0; i<s; i++) t->b[i] = At[(s-1)*s+i];
294e27a552bSJed Brown   if (ct) {ierr = PetscMemcpy(t->ct,ct,s*sizeof(ct[0]));CHKERRQ(ierr);}
295e27a552bSJed Brown   else for (i=0; i<s; i++) for (j=0,t->ct[i]=0; j<s; j++) t->ct[i] += At[i*s+j];
296e27a552bSJed Brown   if (c) {ierr = PetscMemcpy(t->c,c,s*sizeof(c[0]));CHKERRQ(ierr);}
297e27a552bSJed Brown   else for (i=0; i<s; i++) for (j=0,t->c[i]=0; j<s; j++) t->c[i] += A[i*s+j];
298e27a552bSJed Brown   t->pinterp = pinterp;
299e27a552bSJed Brown   ierr = PetscMalloc2(s*pinterp,PetscReal,&t->binterpt,s*pinterp,PetscReal,&t->binterp);CHKERRQ(ierr);
300e27a552bSJed Brown   ierr = PetscMemcpy(t->binterpt,binterpt,s*pinterp*sizeof(binterpt[0]));CHKERRQ(ierr);
301e27a552bSJed Brown   ierr = PetscMemcpy(t->binterp,binterp?binterp:binterpt,s*pinterp*sizeof(binterpt[0]));CHKERRQ(ierr);
302e27a552bSJed Brown   link->next = ARKTableauList;
303e27a552bSJed Brown   ARKTableauList = link;
304e27a552bSJed Brown   PetscFunctionReturn(0);
305e27a552bSJed Brown }
306e27a552bSJed Brown 
307e27a552bSJed Brown #undef __FUNCT__
308e27a552bSJed Brown #define __FUNCT__ "TSStep_RosW"
309e27a552bSJed Brown static PetscErrorCode TSStep_RosW(TS ts)
310e27a552bSJed Brown {
311e27a552bSJed Brown   TS_RosW      *ark = (TS_RosW*)ts->data;
312e27a552bSJed Brown   ARKTableau      tab  = ark->tableau;
313e27a552bSJed Brown   const PetscInt  s    = tab->s;
314e27a552bSJed Brown   const PetscReal *At  = tab->At,*A = tab->A,*bt = tab->bt,*b = tab->b,*ct = tab->ct,*c = tab->c;
315e27a552bSJed Brown   PetscScalar     *w   = ark->work;
316e27a552bSJed Brown   Vec             *Y   = ark->Y,*YdotI = ark->YdotI,*YdotRHS = ark->YdotRHS,Ydot = ark->Ydot,W = ark->Work,Z = ark->Z;
317e27a552bSJed Brown   SNES            snes;
318e27a552bSJed Brown   PetscInt        i,j,its,lits;
319*cdbf8f93SLisandro Dalcin   PetscReal       next_time_step;
320e27a552bSJed Brown   PetscReal       h,t;
321e27a552bSJed Brown   PetscErrorCode  ierr;
322e27a552bSJed Brown 
323e27a552bSJed Brown   PetscFunctionBegin;
324e27a552bSJed Brown   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
325*cdbf8f93SLisandro Dalcin   next_time_step = ts->time_step;
326*cdbf8f93SLisandro Dalcin   h = ts->time_step;
327e27a552bSJed Brown   t = ts->ptime;
328e27a552bSJed Brown 
329e27a552bSJed Brown   for (i=0; i<s; i++) {
330e27a552bSJed Brown     if (At[i*s+i] == 0) {           /* This stage is explicit */
331e27a552bSJed Brown       ierr = VecCopy(ts->vec_sol,Y[i]);CHKERRQ(ierr);
332e27a552bSJed Brown       for (j=0; j<i; j++) w[j] = -h*At[i*s+j];
333e27a552bSJed Brown       ierr = VecMAXPY(Y[i],i,w,YdotI);CHKERRQ(ierr);
334e27a552bSJed Brown       for (j=0; j<i; j++) w[j] = h*A[i*s+j];
335e27a552bSJed Brown       ierr = VecMAXPY(Y[i],i,w,YdotRHS);CHKERRQ(ierr);
336e27a552bSJed Brown     } else {
337e27a552bSJed Brown       ark->stage_time = t + h*ct[i];
338e27a552bSJed Brown       ark->shift = 1./(h*At[i*s+i]);
339e27a552bSJed Brown       /* Affine part */
340e27a552bSJed Brown       ierr = VecZeroEntries(W);CHKERRQ(ierr);
341e27a552bSJed Brown       for (j=0; j<i; j++) w[j] = h*A[i*s+j];
342e27a552bSJed Brown       ierr = VecMAXPY(W,i,w,YdotRHS);CHKERRQ(ierr);
343e27a552bSJed Brown       /* Ydot = shift*(Y-Z) */
344e27a552bSJed Brown       ierr = VecCopy(ts->vec_sol,Z);CHKERRQ(ierr);
345e27a552bSJed Brown       for (j=0; j<i; j++) w[j] = -h*At[i*s+j];
346e27a552bSJed Brown       ierr = VecMAXPY(Z,i,w,YdotI);CHKERRQ(ierr);
347e27a552bSJed Brown       /* Initial guess taken from last stage */
348e27a552bSJed Brown       ierr = VecCopy(i>0?Y[i-1]:ts->vec_sol,Y[i]);CHKERRQ(ierr);
349e27a552bSJed Brown       ierr = SNESSolve(snes,W,Y[i]);CHKERRQ(ierr);
350e27a552bSJed Brown       ierr = SNESGetIterationNumber(snes,&its);CHKERRQ(ierr);
351e27a552bSJed Brown       ierr = SNESGetLinearSolveIterations(snes,&lits);CHKERRQ(ierr);
352e27a552bSJed Brown       ts->nonlinear_its += its; ts->linear_its += lits;
353e27a552bSJed Brown     }
354e27a552bSJed Brown     ierr = VecZeroEntries(Ydot);CHKERRQ(ierr);
355e27a552bSJed Brown     ierr = TSComputeIFunction(ts,t+h*ct[i],Y[i],Ydot,YdotI[i],ark->imex);CHKERRQ(ierr);
356e27a552bSJed Brown     if (ark->imex) {
357e27a552bSJed Brown       ierr = TSComputeRHSFunction(ts,t+h*c[i],Y[i],YdotRHS[i]);CHKERRQ(ierr);
358e27a552bSJed Brown     } else {
359e27a552bSJed Brown       ierr = VecZeroEntries(YdotRHS[i]);CHKERRQ(ierr);
360e27a552bSJed Brown     }
361e27a552bSJed Brown   }
362e27a552bSJed Brown   for (j=0; j<s; j++) w[j] = -h*bt[j];
363e27a552bSJed Brown   ierr = VecMAXPY(ts->vec_sol,s,w,YdotI);CHKERRQ(ierr);
364e27a552bSJed Brown   for (j=0; j<s; j++) w[j] = h*b[j];
365e27a552bSJed Brown   ierr = VecMAXPY(ts->vec_sol,s,w,YdotRHS);CHKERRQ(ierr);
366e27a552bSJed Brown 
367e27a552bSJed Brown   ts->ptime += ts->time_step;
368*cdbf8f93SLisandro Dalcin   ts->time_step_prev = ts->time_step;
369*cdbf8f93SLisandro Dalcin   ts->time_step = next_time_step;
370e27a552bSJed Brown   ts->steps++;
371e27a552bSJed Brown   PetscFunctionReturn(0);
372e27a552bSJed Brown }
373e27a552bSJed Brown 
374e27a552bSJed Brown #undef __FUNCT__
375e27a552bSJed Brown #define __FUNCT__ "TSInterpolate_RosW"
376e27a552bSJed Brown static PetscErrorCode TSInterpolate_RosW(TS ts,PetscReal itime,Vec X)
377e27a552bSJed Brown {
378e27a552bSJed Brown   TS_RosW *ark = (TS_RosW*)ts->data;
379e27a552bSJed Brown   PetscInt s = ark->tableau->s,pinterp = ark->tableau->pinterp,i,j;
380e27a552bSJed Brown   PetscReal tt,t = (itime - ts->ptime)/ts->time_step + 1; /* In the interval [0,1] */
381e27a552bSJed Brown   PetscScalar *bt,*b;
382e27a552bSJed Brown   const PetscReal *Bt = ark->tableau->binterpt,*B = ark->tableau->binterp;
383e27a552bSJed Brown   PetscErrorCode ierr;
384e27a552bSJed Brown 
385e27a552bSJed Brown   PetscFunctionBegin;
386e27a552bSJed Brown   if (!Bt || !B) SETERRQ1(((PetscObject)ts)->comm,PETSC_ERR_SUP,"TSRosW %s does not have an interpolation formula",ark->tableau->name);
387e27a552bSJed Brown   ierr = PetscMalloc2(s,PetscScalar,&bt,s,PetscScalar,&b);CHKERRQ(ierr);
388e27a552bSJed Brown   for (i=0; i<s; i++) bt[i] = b[i] = 0;
389e27a552bSJed Brown   for (j=0,tt=t; j<pinterp; j++,tt*=t) {
390e27a552bSJed Brown     for (i=0; i<s; i++) {
391e27a552bSJed Brown       bt[i] += ts->time_step * Bt[i*pinterp+j] * tt * -1.0;
392e27a552bSJed Brown       b[i]  += ts->time_step * B[i*pinterp+j] * tt;
393e27a552bSJed Brown     }
394e27a552bSJed Brown   }
395e27a552bSJed Brown   if (ark->tableau->At[0*s+0] != 0.0) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_SUP,"First stage not explicit so starting stage not saved");
396e27a552bSJed Brown   ierr = VecCopy(ark->Y[0],X);CHKERRQ(ierr);
397e27a552bSJed Brown   ierr = VecMAXPY(X,s,bt,ark->YdotI);CHKERRQ(ierr);
398e27a552bSJed Brown   ierr = VecMAXPY(X,s,b,ark->YdotRHS);CHKERRQ(ierr);
399e27a552bSJed Brown   ierr = PetscFree2(bt,b);CHKERRQ(ierr);
400e27a552bSJed Brown   PetscFunctionReturn(0);
401e27a552bSJed Brown }
402e27a552bSJed Brown 
403e27a552bSJed Brown /*------------------------------------------------------------*/
404e27a552bSJed Brown #undef __FUNCT__
405e27a552bSJed Brown #define __FUNCT__ "TSReset_RosW"
406e27a552bSJed Brown static PetscErrorCode TSReset_RosW(TS ts)
407e27a552bSJed Brown {
408e27a552bSJed Brown   TS_RosW      *ark = (TS_RosW*)ts->data;
409e27a552bSJed Brown   PetscInt        s;
410e27a552bSJed Brown   PetscErrorCode  ierr;
411e27a552bSJed Brown 
412e27a552bSJed Brown   PetscFunctionBegin;
413e27a552bSJed Brown   if (!ark->tableau) PetscFunctionReturn(0);
414e27a552bSJed Brown    s = ark->tableau->s;
415e27a552bSJed Brown   ierr = VecDestroyVecs(s,&ark->Y);CHKERRQ(ierr);
416e27a552bSJed Brown   ierr = VecDestroyVecs(s,&ark->YdotI);CHKERRQ(ierr);
417e27a552bSJed Brown   ierr = VecDestroyVecs(s,&ark->YdotRHS);CHKERRQ(ierr);
418e27a552bSJed Brown   ierr = VecDestroy(&ark->Ydot);CHKERRQ(ierr);
419e27a552bSJed Brown   ierr = VecDestroy(&ark->Work);CHKERRQ(ierr);
420e27a552bSJed Brown   ierr = VecDestroy(&ark->Z);CHKERRQ(ierr);
421e27a552bSJed Brown   ierr = PetscFree(ark->work);CHKERRQ(ierr);
422e27a552bSJed Brown   PetscFunctionReturn(0);
423e27a552bSJed Brown }
424e27a552bSJed Brown 
425e27a552bSJed Brown #undef __FUNCT__
426e27a552bSJed Brown #define __FUNCT__ "TSDestroy_RosW"
427e27a552bSJed Brown static PetscErrorCode TSDestroy_RosW(TS ts)
428e27a552bSJed Brown {
429e27a552bSJed Brown   PetscErrorCode  ierr;
430e27a552bSJed Brown 
431e27a552bSJed Brown   PetscFunctionBegin;
432e27a552bSJed Brown   ierr = TSReset_RosW(ts);CHKERRQ(ierr);
433e27a552bSJed Brown   ierr = PetscFree(ts->data);CHKERRQ(ierr);
434e27a552bSJed Brown   ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSRosWGetType_C","",PETSC_NULL);CHKERRQ(ierr);
435e27a552bSJed Brown   ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSRosWSetType_C","",PETSC_NULL);CHKERRQ(ierr);
436e27a552bSJed Brown   PetscFunctionReturn(0);
437e27a552bSJed Brown }
438e27a552bSJed Brown 
439e27a552bSJed Brown /*
440e27a552bSJed Brown   This defines the nonlinear equation that is to be solved with SNES
441e27a552bSJed Brown   G(U) = F[t0+Theta*dt, U, (U-U0)*shift] = 0
442e27a552bSJed Brown */
443e27a552bSJed Brown #undef __FUNCT__
444e27a552bSJed Brown #define __FUNCT__ "SNESTSFormFunction_RosW"
445e27a552bSJed Brown static PetscErrorCode SNESTSFormFunction_RosW(SNES snes,Vec X,Vec F,TS ts)
446e27a552bSJed Brown {
447e27a552bSJed Brown   TS_RosW     *ark = (TS_RosW*)ts->data;
448e27a552bSJed Brown   PetscErrorCode ierr;
449e27a552bSJed Brown 
450e27a552bSJed Brown   PetscFunctionBegin;
451e27a552bSJed Brown   ierr = VecAXPBYPCZ(ark->Ydot,-ark->shift,ark->shift,0,ark->Z,X);CHKERRQ(ierr); /* Ydot = shift*(X-Z) */
452e27a552bSJed Brown   ierr = TSComputeIFunction(ts,ark->stage_time,X,ark->Ydot,F,ark->imex);CHKERRQ(ierr);
453e27a552bSJed Brown   PetscFunctionReturn(0);
454e27a552bSJed Brown }
455e27a552bSJed Brown 
456e27a552bSJed Brown #undef __FUNCT__
457e27a552bSJed Brown #define __FUNCT__ "SNESTSFormJacobian_RosW"
458e27a552bSJed Brown static PetscErrorCode SNESTSFormJacobian_RosW(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *str,TS ts)
459e27a552bSJed Brown {
460e27a552bSJed Brown   TS_RosW       *ark = (TS_RosW*)ts->data;
461e27a552bSJed Brown   PetscErrorCode ierr;
462e27a552bSJed Brown 
463e27a552bSJed Brown   PetscFunctionBegin;
464e27a552bSJed Brown   /* ark->Ydot has already been computed in SNESTSFormFunction_RosW (SNES guarantees this) */
465e27a552bSJed Brown   ierr = TSComputeIJacobian(ts,ark->stage_time,X,ark->Ydot,ark->shift,A,B,str,PETSC_TRUE);CHKERRQ(ierr);
466e27a552bSJed Brown   PetscFunctionReturn(0);
467e27a552bSJed Brown }
468e27a552bSJed Brown 
469e27a552bSJed Brown #undef __FUNCT__
470e27a552bSJed Brown #define __FUNCT__ "TSSetUp_RosW"
471e27a552bSJed Brown static PetscErrorCode TSSetUp_RosW(TS ts)
472e27a552bSJed Brown {
473e27a552bSJed Brown   TS_RosW     *ark = (TS_RosW*)ts->data;
474e27a552bSJed Brown   ARKTableau     tab  = ark->tableau;
475e27a552bSJed Brown   PetscInt       s = tab->s;
476e27a552bSJed Brown   PetscErrorCode ierr;
477e27a552bSJed Brown 
478e27a552bSJed Brown   PetscFunctionBegin;
479e27a552bSJed Brown   if (!ark->tableau) {
480e27a552bSJed Brown     ierr = TSRosWSetType(ts,TSRosWDefault);CHKERRQ(ierr);
481e27a552bSJed Brown   }
482e27a552bSJed Brown   ierr = VecDuplicateVecs(ts->vec_sol,s,&ark->Y);CHKERRQ(ierr);
483e27a552bSJed Brown   ierr = VecDuplicateVecs(ts->vec_sol,s,&ark->YdotI);CHKERRQ(ierr);
484e27a552bSJed Brown   ierr = VecDuplicateVecs(ts->vec_sol,s,&ark->YdotRHS);CHKERRQ(ierr);
485e27a552bSJed Brown   ierr = VecDuplicate(ts->vec_sol,&ark->Ydot);CHKERRQ(ierr);
486e27a552bSJed Brown   ierr = VecDuplicate(ts->vec_sol,&ark->Work);CHKERRQ(ierr);
487e27a552bSJed Brown   ierr = VecDuplicate(ts->vec_sol,&ark->Z);CHKERRQ(ierr);
488e27a552bSJed Brown   ierr = PetscMalloc(s*sizeof(ark->work[0]),&ark->work);CHKERRQ(ierr);
489e27a552bSJed Brown   PetscFunctionReturn(0);
490e27a552bSJed Brown }
491e27a552bSJed Brown /*------------------------------------------------------------*/
492e27a552bSJed Brown 
493e27a552bSJed Brown #undef __FUNCT__
494e27a552bSJed Brown #define __FUNCT__ "TSSetFromOptions_RosW"
495e27a552bSJed Brown static PetscErrorCode TSSetFromOptions_RosW(TS ts)
496e27a552bSJed Brown {
497e27a552bSJed Brown   TS_RosW     *ark = (TS_RosW*)ts->data;
498e27a552bSJed Brown   PetscErrorCode ierr;
499e27a552bSJed Brown   char           arktype[256];
500e27a552bSJed Brown 
501e27a552bSJed Brown   PetscFunctionBegin;
502e27a552bSJed Brown   ierr = PetscOptionsHead("RosW ODE solver options");CHKERRQ(ierr);
503e27a552bSJed Brown   {
504e27a552bSJed Brown     ARKTableauLink link;
505e27a552bSJed Brown     PetscInt count,choice;
506e27a552bSJed Brown     PetscBool flg;
507e27a552bSJed Brown     const char **namelist;
508e27a552bSJed Brown     ierr = PetscStrncpy(arktype,TSRosWDefault,sizeof arktype);CHKERRQ(ierr);
509e27a552bSJed Brown     for (link=ARKTableauList,count=0; link; link=link->next,count++) ;
510e27a552bSJed Brown     ierr = PetscMalloc(count*sizeof(char*),&namelist);CHKERRQ(ierr);
511e27a552bSJed Brown     for (link=ARKTableauList,count=0; link; link=link->next,count++) namelist[count] = link->tab.name;
512e27a552bSJed Brown     ierr = PetscOptionsEList("-ts_rosw_type","Family of ARK IMEX method","TSRosWSetType",(const char*const*)namelist,count,arktype,&choice,&flg);CHKERRQ(ierr);
513e27a552bSJed Brown     ierr = TSRosWSetType(ts,flg ? namelist[choice] : arktype);CHKERRQ(ierr);
514e27a552bSJed Brown     ierr = PetscFree(namelist);CHKERRQ(ierr);
515e27a552bSJed Brown     flg = (PetscBool)!ark->imex;
516e27a552bSJed Brown     ierr = PetscOptionsBool("-ts_rosw_fully_implicit","Solve the problem fully implicitly","TSRosWSetFullyImplicit",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
517e27a552bSJed Brown     ark->imex = (PetscBool)!flg;
518e27a552bSJed Brown     ierr = SNESSetFromOptions(ts->snes);CHKERRQ(ierr);
519e27a552bSJed Brown   }
520e27a552bSJed Brown   ierr = PetscOptionsTail();CHKERRQ(ierr);
521e27a552bSJed Brown   PetscFunctionReturn(0);
522e27a552bSJed Brown }
523e27a552bSJed Brown 
524e27a552bSJed Brown #undef __FUNCT__
525e27a552bSJed Brown #define __FUNCT__ "PetscFormatRealArray"
526e27a552bSJed Brown static PetscErrorCode PetscFormatRealArray(char buf[],size_t len,const char *fmt,PetscInt n,const PetscReal x[])
527e27a552bSJed Brown {
528e27a552bSJed Brown   PetscErrorCode ierr;
529e27a552bSJed Brown   int i,left,count;
530e27a552bSJed Brown   char *p;
531e27a552bSJed Brown 
532e27a552bSJed Brown   PetscFunctionBegin;
533e27a552bSJed Brown   for (i=0,p=buf,left=(int)len; i<n; i++) {
534e27a552bSJed Brown     ierr = PetscSNPrintf(p,left,fmt,&count,x[i]);CHKERRQ(ierr);
535e27a552bSJed Brown     if (count >= left) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Insufficient space in buffer");
536e27a552bSJed Brown     left -= count;
537e27a552bSJed Brown     p += count;
538e27a552bSJed Brown     *p++ = ' ';
539e27a552bSJed Brown   }
540e27a552bSJed Brown   p[i ? 0 : -1] = 0;
541e27a552bSJed Brown   PetscFunctionReturn(0);
542e27a552bSJed Brown }
543e27a552bSJed Brown 
544e27a552bSJed Brown #undef __FUNCT__
545e27a552bSJed Brown #define __FUNCT__ "TSView_RosW"
546e27a552bSJed Brown static PetscErrorCode TSView_RosW(TS ts,PetscViewer viewer)
547e27a552bSJed Brown {
548e27a552bSJed Brown   TS_RosW     *ark = (TS_RosW*)ts->data;
549e27a552bSJed Brown   ARKTableau     tab = ark->tableau;
550e27a552bSJed Brown   PetscBool      iascii;
551e27a552bSJed Brown   PetscErrorCode ierr;
552e27a552bSJed Brown 
553e27a552bSJed Brown   PetscFunctionBegin;
554e27a552bSJed Brown   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
555e27a552bSJed Brown   if (iascii) {
556e27a552bSJed Brown     const TSRosWType arktype;
557e27a552bSJed Brown     char buf[512];
558e27a552bSJed Brown     ierr = TSRosWGetType(ts,&arktype);CHKERRQ(ierr);
559e27a552bSJed Brown     ierr = PetscViewerASCIIPrintf(viewer,"  ARK IMEX %s\n",arktype);CHKERRQ(ierr);
560e27a552bSJed Brown     ierr = PetscFormatRealArray(buf,sizeof buf,"% 8.6f",tab->s,tab->ct);CHKERRQ(ierr);
561e27a552bSJed Brown     ierr = PetscViewerASCIIPrintf(viewer,"  Stiff abscissa       ct = %s\n",buf);CHKERRQ(ierr);
562e27a552bSJed Brown     ierr = PetscFormatRealArray(buf,sizeof buf,"% 8.6f",tab->s,tab->c);CHKERRQ(ierr);
563e27a552bSJed Brown     ierr = PetscViewerASCIIPrintf(viewer,"  Nonstiff abscissa     c = %s\n",buf);CHKERRQ(ierr);
564e27a552bSJed Brown   }
565e27a552bSJed Brown   ierr = SNESView(ts->snes,viewer);CHKERRQ(ierr);
566e27a552bSJed Brown   PetscFunctionReturn(0);
567e27a552bSJed Brown }
568e27a552bSJed Brown 
569e27a552bSJed Brown #undef __FUNCT__
570e27a552bSJed Brown #define __FUNCT__ "TSRosWSetType"
571e27a552bSJed Brown /*@C
572e27a552bSJed Brown   TSRosWSetType - Set the type of ARK IMEX scheme
573e27a552bSJed Brown 
574e27a552bSJed Brown   Logically collective
575e27a552bSJed Brown 
576e27a552bSJed Brown   Input Parameter:
577e27a552bSJed Brown +  ts - timestepping context
578e27a552bSJed Brown -  arktype - type of ARK-IMEX scheme
579e27a552bSJed Brown 
580e27a552bSJed Brown   Level: intermediate
581e27a552bSJed Brown 
582e27a552bSJed Brown .seealso: TSRosWGetType()
583e27a552bSJed Brown @*/
584e27a552bSJed Brown PetscErrorCode TSRosWSetType(TS ts,const TSRosWType arktype)
585e27a552bSJed Brown {
586e27a552bSJed Brown   PetscErrorCode ierr;
587e27a552bSJed Brown 
588e27a552bSJed Brown   PetscFunctionBegin;
589e27a552bSJed Brown   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
590e27a552bSJed Brown   ierr = PetscTryMethod(ts,"TSRosWSetType_C",(TS,const TSRosWType),(ts,arktype));CHKERRQ(ierr);
591e27a552bSJed Brown   PetscFunctionReturn(0);
592e27a552bSJed Brown }
593e27a552bSJed Brown 
594e27a552bSJed Brown #undef __FUNCT__
595e27a552bSJed Brown #define __FUNCT__ "TSRosWGetType"
596e27a552bSJed Brown /*@C
597e27a552bSJed Brown   TSRosWGetType - Get the type of ARK IMEX scheme
598e27a552bSJed Brown 
599e27a552bSJed Brown   Logically collective
600e27a552bSJed Brown 
601e27a552bSJed Brown   Input Parameter:
602e27a552bSJed Brown .  ts - timestepping context
603e27a552bSJed Brown 
604e27a552bSJed Brown   Output Parameter:
605e27a552bSJed Brown .  arktype - type of ARK-IMEX scheme
606e27a552bSJed Brown 
607e27a552bSJed Brown   Level: intermediate
608e27a552bSJed Brown 
609e27a552bSJed Brown .seealso: TSRosWGetType()
610e27a552bSJed Brown @*/
611e27a552bSJed Brown PetscErrorCode TSRosWGetType(TS ts,const TSRosWType *arktype)
612e27a552bSJed Brown {
613e27a552bSJed Brown   PetscErrorCode ierr;
614e27a552bSJed Brown 
615e27a552bSJed Brown   PetscFunctionBegin;
616e27a552bSJed Brown   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
617e27a552bSJed Brown   ierr = PetscUseMethod(ts,"TSRosWGetType_C",(TS,const TSRosWType*),(ts,arktype));CHKERRQ(ierr);
618e27a552bSJed Brown   PetscFunctionReturn(0);
619e27a552bSJed Brown }
620e27a552bSJed Brown 
621e27a552bSJed Brown #undef __FUNCT__
622e27a552bSJed Brown #define __FUNCT__ "TSRosWSetFullyImplicit"
623e27a552bSJed Brown /*@C
624e27a552bSJed Brown   TSRosWSetFullyImplicit - Solve both parts of the equation implicitly
625e27a552bSJed Brown 
626e27a552bSJed Brown   Logically collective
627e27a552bSJed Brown 
628e27a552bSJed Brown   Input Parameter:
629e27a552bSJed Brown +  ts - timestepping context
630e27a552bSJed Brown -  flg - PETSC_TRUE for fully implicit
631e27a552bSJed Brown 
632e27a552bSJed Brown   Level: intermediate
633e27a552bSJed Brown 
634e27a552bSJed Brown .seealso: TSRosWGetType()
635e27a552bSJed Brown @*/
636e27a552bSJed Brown PetscErrorCode TSRosWSetFullyImplicit(TS ts,PetscBool flg)
637e27a552bSJed Brown {
638e27a552bSJed Brown   PetscErrorCode ierr;
639e27a552bSJed Brown 
640e27a552bSJed Brown   PetscFunctionBegin;
641e27a552bSJed Brown   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
642e27a552bSJed Brown   ierr = PetscTryMethod(ts,"TSRosWSetFullyImplicit_C",(TS,PetscBool),(ts,flg));CHKERRQ(ierr);
643e27a552bSJed Brown   PetscFunctionReturn(0);
644e27a552bSJed Brown }
645e27a552bSJed Brown 
646e27a552bSJed Brown EXTERN_C_BEGIN
647e27a552bSJed Brown #undef __FUNCT__
648e27a552bSJed Brown #define __FUNCT__ "TSRosWGetType_RosW"
649e27a552bSJed Brown PetscErrorCode  TSRosWGetType_RosW(TS ts,const TSRosWType *arktype)
650e27a552bSJed Brown {
651e27a552bSJed Brown   TS_RosW *ark = (TS_RosW*)ts->data;
652e27a552bSJed Brown   PetscErrorCode ierr;
653e27a552bSJed Brown 
654e27a552bSJed Brown   PetscFunctionBegin;
655e27a552bSJed Brown   if (!ark->tableau) {ierr = TSRosWSetType(ts,TSRosWDefault);CHKERRQ(ierr);}
656e27a552bSJed Brown   *arktype = ark->tableau->name;
657e27a552bSJed Brown   PetscFunctionReturn(0);
658e27a552bSJed Brown }
659e27a552bSJed Brown #undef __FUNCT__
660e27a552bSJed Brown #define __FUNCT__ "TSRosWSetType_RosW"
661e27a552bSJed Brown PetscErrorCode  TSRosWSetType_RosW(TS ts,const TSRosWType arktype)
662e27a552bSJed Brown {
663e27a552bSJed Brown   TS_RosW *ark = (TS_RosW*)ts->data;
664e27a552bSJed Brown   PetscErrorCode ierr;
665e27a552bSJed Brown   PetscBool match;
666e27a552bSJed Brown   ARKTableauLink link;
667e27a552bSJed Brown 
668e27a552bSJed Brown   PetscFunctionBegin;
669e27a552bSJed Brown   if (ark->tableau) {
670e27a552bSJed Brown     ierr = PetscStrcmp(ark->tableau->name,arktype,&match);CHKERRQ(ierr);
671e27a552bSJed Brown     if (match) PetscFunctionReturn(0);
672e27a552bSJed Brown   }
673e27a552bSJed Brown   for (link = ARKTableauList; link; link=link->next) {
674e27a552bSJed Brown     ierr = PetscStrcmp(link->tab.name,arktype,&match);CHKERRQ(ierr);
675e27a552bSJed Brown     if (match) {
676e27a552bSJed Brown       ierr = TSReset_RosW(ts);CHKERRQ(ierr);
677e27a552bSJed Brown       ark->tableau = &link->tab;
678e27a552bSJed Brown       PetscFunctionReturn(0);
679e27a552bSJed Brown     }
680e27a552bSJed Brown   }
681e27a552bSJed Brown   SETERRQ1(((PetscObject)ts)->comm,PETSC_ERR_ARG_UNKNOWN_TYPE,"Could not find '%s'",arktype);
682e27a552bSJed Brown   PetscFunctionReturn(0);
683e27a552bSJed Brown }
684e27a552bSJed Brown #undef __FUNCT__
685e27a552bSJed Brown #define __FUNCT__ "TSRosWSetFullyImplicit_RosW"
686e27a552bSJed Brown PetscErrorCode  TSRosWSetFullyImplicit_RosW(TS ts,PetscBool flg)
687e27a552bSJed Brown {
688e27a552bSJed Brown   TS_RosW *ark = (TS_RosW*)ts->data;
689e27a552bSJed Brown 
690e27a552bSJed Brown   PetscFunctionBegin;
691e27a552bSJed Brown   ark->imex = (PetscBool)!flg;
692e27a552bSJed Brown   PetscFunctionReturn(0);
693e27a552bSJed Brown }
694e27a552bSJed Brown EXTERN_C_END
695e27a552bSJed Brown 
696e27a552bSJed Brown /* ------------------------------------------------------------ */
697e27a552bSJed Brown /*MC
698e27a552bSJed Brown       TSRosW - ODE solver using Rosenbrock-W schemes
699e27a552bSJed Brown 
700e27a552bSJed Brown   These methods are intended for problems with well-separated time scales, especially when a slow scale is strongly
701e27a552bSJed Brown   nonlinear such that it is expensive to solve with a fully implicit method. The user should provide the stiff part
702e27a552bSJed Brown   of the equation using TSSetIFunction() and the non-stiff part with TSSetRHSFunction().
703e27a552bSJed Brown 
704e27a552bSJed Brown   Notes:
705e27a552bSJed Brown   This method currently only works with ODE, for which the stiff part G(t,X,Xdot) has the form Xdot + Ghat(t,X).
706e27a552bSJed Brown 
707e27a552bSJed Brown   Level: beginner
708e27a552bSJed Brown 
709e27a552bSJed Brown .seealso:  TSCreate(), TS, TSSetType(), TSRosWRegister()
710e27a552bSJed Brown 
711e27a552bSJed Brown M*/
712e27a552bSJed Brown EXTERN_C_BEGIN
713e27a552bSJed Brown #undef __FUNCT__
714e27a552bSJed Brown #define __FUNCT__ "TSCreate_RosW"
715e27a552bSJed Brown PetscErrorCode  TSCreate_RosW(TS ts)
716e27a552bSJed Brown {
717e27a552bSJed Brown   TS_RosW       *th;
718e27a552bSJed Brown   PetscErrorCode ierr;
719e27a552bSJed Brown 
720e27a552bSJed Brown   PetscFunctionBegin;
721e27a552bSJed Brown #if !defined(PETSC_USE_DYNAMIC_LIBRARIES)
722e27a552bSJed Brown   ierr = TSRosWInitializePackage(PETSC_NULL);CHKERRQ(ierr);
723e27a552bSJed Brown #endif
724e27a552bSJed Brown 
725e27a552bSJed Brown   ts->ops->reset          = TSReset_RosW;
726e27a552bSJed Brown   ts->ops->destroy        = TSDestroy_RosW;
727e27a552bSJed Brown   ts->ops->view           = TSView_RosW;
728e27a552bSJed Brown   ts->ops->setup          = TSSetUp_RosW;
729e27a552bSJed Brown   ts->ops->step           = TSStep_RosW;
730e27a552bSJed Brown   ts->ops->interpolate    = TSInterpolate_RosW;
731e27a552bSJed Brown   ts->ops->setfromoptions = TSSetFromOptions_RosW;
732e27a552bSJed Brown   ts->ops->snesfunction   = SNESTSFormFunction_RosW;
733e27a552bSJed Brown   ts->ops->snesjacobian   = SNESTSFormJacobian_RosW;
734e27a552bSJed Brown 
735e27a552bSJed Brown   ierr = PetscNewLog(ts,TS_RosW,&th);CHKERRQ(ierr);
736e27a552bSJed Brown   ts->data = (void*)th;
737e27a552bSJed Brown   th->imex = PETSC_TRUE;
738e27a552bSJed Brown 
739e27a552bSJed Brown   ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSRosWGetType_C","TSRosWGetType_RosW",TSRosWGetType_RosW);CHKERRQ(ierr);
740e27a552bSJed Brown   ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSRosWSetType_C","TSRosWSetType_RosW",TSRosWSetType_RosW);CHKERRQ(ierr);
741e27a552bSJed Brown   ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSRosWSetFullyImplicit_C","TSRosWSetFullyImplicit_RosW",TSRosWSetFullyImplicit_RosW);CHKERRQ(ierr);
742e27a552bSJed Brown   PetscFunctionReturn(0);
743e27a552bSJed Brown }
744e27a552bSJed Brown EXTERN_C_END
745