xref: /petsc/src/ts/impls/arkimex/arkimex.c (revision cd6526761e44e2ac7b4afaaf511785e78693abcc)
18a381b04SJed Brown /*
28a381b04SJed Brown   Code for timestepping with additive Runge-Kutta IMEX method
38a381b04SJed Brown 
48a381b04SJed Brown   Notes:
58a381b04SJed Brown   The general system is written as
68a381b04SJed Brown 
78a381b04SJed Brown   F(t,X,Xdot) = G(t,X)
88a381b04SJed Brown 
98a381b04SJed Brown   where F represents the stiff part of the physics and G represents the non-stiff part.
108a381b04SJed Brown 
118a381b04SJed Brown */
128a381b04SJed Brown #include <private/tsimpl.h>                /*I   "petscts.h"   I*/
138a381b04SJed Brown 
148a381b04SJed Brown static const TSARKIMEXType TSARKIMEXDefault = TSARKIMEX2D;
158a381b04SJed Brown static PetscBool TSARKIMEXRegisterAllCalled;
168a381b04SJed Brown static PetscBool TSARKIMEXPackageInitialized;
178a381b04SJed Brown 
188a381b04SJed Brown typedef struct _ARKTableau *ARKTableau;
198a381b04SJed Brown struct _ARKTableau {
208a381b04SJed Brown   char *name;
218a381b04SJed Brown   PetscInt order;
228a381b04SJed Brown   PetscInt s;
238a381b04SJed Brown   PetscReal *At,*bt,*ct;
248a381b04SJed Brown   PetscReal *A,*b,*c;           /* Non-stiff tableau */
25*cd652676SJed Brown   PetscReal *binterpt,*binterp; /* Dense output formula */
268a381b04SJed Brown };
278a381b04SJed Brown typedef struct _ARKTableauLink *ARKTableauLink;
288a381b04SJed Brown struct _ARKTableauLink {
298a381b04SJed Brown   struct _ARKTableau tab;
308a381b04SJed Brown   ARKTableauLink next;
318a381b04SJed Brown };
328a381b04SJed Brown static ARKTableauLink ARKTableauList;
338a381b04SJed Brown 
348a381b04SJed Brown typedef struct {
358a381b04SJed Brown   ARKTableau  tableau;
368a381b04SJed Brown   Vec         *Y;               /* States computed during the step */
378a381b04SJed Brown   Vec         *YdotI;           /* Time derivatives for the stiff part */
388a381b04SJed Brown   Vec         *YdotRHS;         /* Function evaluations for the non-stiff part */
398a381b04SJed Brown   Vec         Ydot;             /* Work vector holding Ydot during residual evaluation */
408a381b04SJed Brown   Vec         Work;             /* Generic work vector */
418a381b04SJed Brown   Vec         Z;                /* Ydot = shift(Y-Z) */
428a381b04SJed Brown   PetscScalar *work;            /* Scalar work */
438a381b04SJed Brown   PetscReal   shift;
448a381b04SJed Brown   PetscReal   stage_time;
458a381b04SJed Brown } TS_ARKIMEX;
468a381b04SJed Brown 
478a381b04SJed Brown #undef __FUNCT__
488a381b04SJed Brown #define __FUNCT__ "TSARKIMEXRegisterAll"
498a381b04SJed Brown /*@C
508a381b04SJed Brown   TSARKIMEXRegisterAll - Registers all of the additive Runge-Kutta implicit-explicit methods in TSARKIMEX
518a381b04SJed Brown 
52fca742c7SJed Brown   Not Collective, but should be called by all processes which will need the schemes to be registered
538a381b04SJed Brown 
548a381b04SJed Brown   Level: advanced
558a381b04SJed Brown 
568a381b04SJed Brown .keywords: TS, TSARKIMEX, register, all
578a381b04SJed Brown 
588a381b04SJed Brown .seealso:  TSARKIMEXRegisterDestroy()
598a381b04SJed Brown @*/
608a381b04SJed Brown PetscErrorCode TSARKIMEXRegisterAll(void)
618a381b04SJed Brown {
628a381b04SJed Brown   PetscErrorCode ierr;
638a381b04SJed Brown 
648a381b04SJed Brown   PetscFunctionBegin;
658a381b04SJed Brown   if (TSARKIMEXRegisterAllCalled) PetscFunctionReturn(0);
668a381b04SJed Brown   TSARKIMEXRegisterAllCalled = PETSC_TRUE;
678a381b04SJed Brown 
688a381b04SJed Brown   {
698a381b04SJed Brown     const PetscReal
708a381b04SJed Brown       A[3][3] = {{0,0,0},
718a381b04SJed Brown                  {0.41421356237309504880,0,0},
728a381b04SJed Brown                  {0.75,0.25,0}},
738a381b04SJed Brown       At[3][3] = {{0,0,0},
748a381b04SJed Brown                   {0.12132034355964257320,0.29289321881345247560,0},
758a381b04SJed Brown                   {0.20710678118654752440,0.50000000000000000000,0.29289321881345247560}};
76*cd652676SJed Brown     ierr = TSARKIMEXRegister(TSARKIMEX2D,2,3,&At[0][0],PETSC_NULL,PETSC_NULL,&A[0][0],PETSC_NULL,PETSC_NULL,0,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
778a381b04SJed Brown   }
78a3a57f36SJed Brown   {
79a3a57f36SJed Brown     const PetscReal s2 = sqrt(2),
80a3a57f36SJed Brown       A[3][3] = {{0,0,0},
81a3a57f36SJed Brown                  {2-s2,0,0},
82a3a57f36SJed Brown                  {(3-2*s2)/6,(3+2*s2)/6,0}},
83a3a57f36SJed Brown       At[3][3] = {{0,0,0},
84a3a57f36SJed Brown                   {1-1/s2,1-1/s2,0},
85*cd652676SJed Brown                   {1/(2*s2),1/(2*s2),1-1/s2}},
86*cd652676SJed Brown       binterpt[3][2] = {{1,-0.5},{0,0},{0,0.5}};
87*cd652676SJed Brown     ierr = TSARKIMEXRegister(TSARKIMEX2E,2,3,&At[0][0],PETSC_NULL,PETSC_NULL,&A[0][0],PETSC_NULL,PETSC_NULL,2,binterpt[0],PETSC_NULL);CHKERRQ(ierr);
88a3a57f36SJed Brown   }
89a3a57f36SJed Brown   {
90a3a57f36SJed Brown     const PetscReal
91a3a57f36SJed Brown       A[4][4] = {{0,0,0,0},
92a3a57f36SJed Brown                  {1767732205903./2027836641118,0,0,0},
93a3a57f36SJed Brown                  {5535828885825./10492691773637,788022342437./10882634858940,0,0},
94a3a57f36SJed Brown                  {6485989280629./16251701735622,-4246266847089./9704473918619,10755448449292./10357097424841,0}},
95a3a57f36SJed Brown       At[4][4] = {{0,0,0,0},
96a3a57f36SJed Brown                   {1767732205903./4055673282236,1767732205903./4055673282236,0,0},
97a3a57f36SJed Brown                   {2746238789719./10658868560708,-640167445237./6845629431997,1767732205903./4055673282236,0},
98*cd652676SJed Brown                   {1471266399579./7840856788654,-4482444167858./7529755066697,11266239266428./11593286722821,1767732205903./4055673282236}},
99*cd652676SJed Brown       binterpt[4][2] = {{4655552711362./22874653954995, -215264564351./13552729205753},
100*cd652676SJed Brown                         {-18682724506714./9892148508045,17870216137069./13817060693119},
101*cd652676SJed Brown                         {34259539580243./13192909600954,-28141676662227./17317692491321},
102*cd652676SJed Brown                         {584795268549./6622622206610,   2508943948391./7218656332882}};
103*cd652676SJed Brown     ierr = TSARKIMEXRegister(TSARKIMEX3,3,4,&At[0][0],PETSC_NULL,PETSC_NULL,&A[0][0],PETSC_NULL,PETSC_NULL,2,binterpt[0],PETSC_NULL);CHKERRQ(ierr);
104a3a57f36SJed Brown   }
105a3a57f36SJed Brown   {
106a3a57f36SJed Brown     const PetscReal
107a3a57f36SJed Brown       A[6][6] = {{0,0,0,0,0,0},
108a3a57f36SJed Brown                  {1./2,0,0,0,0,0},
109a3a57f36SJed Brown                  {13861./62500,6889./62500,0,0,0,0},
110a3a57f36SJed Brown                  {-116923316275./2393684061468,-2731218467317./15368042101831,9408046702089./11113171139209,0,0,0},
111a3a57f36SJed Brown                  {-451086348788./2902428689909,-2682348792572./7519795681897,12662868775082./11960479115383,3355817975965./11060851509271,0,0},
112a3a57f36SJed Brown                  {647845179188./3216320057751,73281519250./8382639484533,552539513391./3454668386233,3354512671639./8306763924573,4040./17871,0}},
113a3a57f36SJed Brown       At[6][6] = {{0,0,0,0,0,0},
114a3a57f36SJed Brown                   {1./4,1./4,0,0,0,0},
115a3a57f36SJed Brown                   {8611./62500,-1743./31250,1./4,0,0,0},
116a3a57f36SJed Brown                   {5012029./34652500,-654441./2922500,174375./388108,1./4,0,0},
117a3a57f36SJed Brown                   {15267082809./155376265600,-71443401./120774400,730878875./902184768,2285395./8070912,1./4,0},
118*cd652676SJed Brown                   {82889./524892,0,15625./83664,69875./102672,-2260./8211,1./4}},
119*cd652676SJed Brown       binterpt[6][3] = {{6943876665148./7220017795957,-54480133./30881146,6818779379841./7100303317025},
120*cd652676SJed Brown                         {0,0,0},
121*cd652676SJed Brown                         {7640104374378./9702883013639,-11436875./14766696,2173542590792./12501825683035},
122*cd652676SJed Brown                         {-20649996744609./7521556579894,174696575./18121608,-31592104683404./5083833661969},
123*cd652676SJed Brown                         {8854892464581./2390941311638,-12120380./966161,61146701046299./7138195549469},
124*cd652676SJed Brown                         {-11397109935349./6675773540249,3843./706,-17219254887155./4939391667607}};
125*cd652676SJed Brown     ierr = TSARKIMEXRegister(TSARKIMEX4,4,6,&At[0][0],PETSC_NULL,PETSC_NULL,&A[0][0],PETSC_NULL,PETSC_NULL,3,binterpt[0],PETSC_NULL);CHKERRQ(ierr);
126a3a57f36SJed Brown   }
127a3a57f36SJed Brown   {
128a3a57f36SJed Brown     const PetscReal
129a3a57f36SJed Brown       A[8][8] = {{0,0,0,0,0,0,0,0},
130a3a57f36SJed Brown                  {41./100,0,0,0,0,0,0,0},
131a3a57f36SJed Brown                  {367902744464./2072280473677,677623207551./8224143866563,0,0,0,0,0,0},
132a3a57f36SJed Brown                  {1268023523408./10340822734521,0,1029933939417./13636558850479,0,0,0,0,0},
133a3a57f36SJed Brown                  {14463281900351./6315353703477,0,66114435211212./5879490589093,-54053170152839./4284798021562,0,0,0,0},
134a3a57f36SJed Brown                  {14090043504691./34967701212078,0,15191511035443./11219624916014,-18461159152457./12425892160975,-281667163811./9011619295870,0,0,0},
135a3a57f36SJed Brown                  {19230459214898./13134317526959,0,21275331358303./2942455364971,-38145345988419./4862620318723,-1./8,-1./8,0,0},
136a3a57f36SJed Brown                  {-19977161125411./11928030595625,0,-40795976796054./6384907823539,177454434618887./12078138498510,782672205425./8267701900261,-69563011059811./9646580694205,7356628210526./4942186776405,0}},
137a3a57f36SJed Brown       At[8][8] = {{0,0,0,0,0,0,0,0},
138a3a57f36SJed Brown                   {41./200,41./200,0,0,0,0,0,0},
139a3a57f36SJed Brown                   {41./400,-567603406766./11931857230679,41./200,0,0,0,0,0},
140a3a57f36SJed Brown                   {683785636431./9252920307686,0,-110385047103./1367015193373,41./200,0,0,0,0},
141a3a57f36SJed Brown                   {3016520224154./10081342136671,0,30586259806659./12414158314087,-22760509404356./11113319521817,41./200,0,0,0},
142a3a57f36SJed Brown                   {218866479029./1489978393911,0,638256894668./5436446318841,-1179710474555./5321154724896,-60928119172./8023461067671,41./200,0,0},
143a3a57f36SJed Brown                   {1020004230633./5715676835656,0,25762820946817./25263940353407,-2161375909145./9755907335909,-211217309593./5846859502534,-4269925059573./7827059040749,41./200,0},
144*cd652676SJed Brown                   {-872700587467./9133579230613,0,0,22348218063261./9555858737531,-1143369518992./8141816002931,-39379526789629./19018526304540,32727382324388./42900044865799,41./200}},
145*cd652676SJed Brown       binterpt[8][3] = {{-17674230611817./10670229744614 ,  43486358583215./12773830924787 , -9257016797708./5021505065439},
146*cd652676SJed Brown                         {0                               ,  0                              , 0                            },
147*cd652676SJed Brown                         {0                               ,  0                              , 0                            },
148*cd652676SJed Brown                         {65168852399939./7868540260826   ,  -91478233927265./11067650958493, 26096422576131./11239449250142},
149*cd652676SJed Brown                         {15494834004392./5936557850923   ,  -79368583304911./10890268929626, 92396832856987./20362823103730},
150*cd652676SJed Brown                         {-99329723586156./26959484932159 ,  -12239297817655./9152339842473 , 30029262896817./10175596800299},
151*cd652676SJed Brown                         {-19024464361622./5461577185407  ,  115839755401235./10719374521269, -26136350496073./3983972220547},
152*cd652676SJed Brown                         {-6511271360970./6095937251113   ,  5843115559534./2180450260947   , -5289405421727./3760307252460 }};
153*cd652676SJed Brown     ierr = TSARKIMEXRegister(TSARKIMEX5,5,8,&At[0][0],PETSC_NULL,PETSC_NULL,&A[0][0],PETSC_NULL,PETSC_NULL,3,binterpt[0],PETSC_NULL);CHKERRQ(ierr);
154a3a57f36SJed Brown   }
155a3a57f36SJed Brown 
1568a381b04SJed Brown   PetscFunctionReturn(0);
1578a381b04SJed Brown }
1588a381b04SJed Brown 
1598a381b04SJed Brown #undef __FUNCT__
1608a381b04SJed Brown #define __FUNCT__ "TSARKIMEXRegisterDestroy"
1618a381b04SJed Brown /*@C
1628a381b04SJed Brown    TSARKIMEXRegisterDestroy - Frees the list of schemes that were registered by TSARKIMEXRegister().
1638a381b04SJed Brown 
1648a381b04SJed Brown    Not Collective
1658a381b04SJed Brown 
1668a381b04SJed Brown    Level: advanced
1678a381b04SJed Brown 
1688a381b04SJed Brown .keywords: TSARKIMEX, register, destroy
1698a381b04SJed Brown .seealso: TSARKIMEXRegister(), TSARKIMEXRegisterAll(), TSARKIMEXRegisterDynamic()
1708a381b04SJed Brown @*/
1718a381b04SJed Brown PetscErrorCode TSARKIMEXRegisterDestroy(void)
1728a381b04SJed Brown {
1738a381b04SJed Brown   PetscErrorCode ierr;
1748a381b04SJed Brown   ARKTableauLink link;
1758a381b04SJed Brown 
1768a381b04SJed Brown   PetscFunctionBegin;
1778a381b04SJed Brown   while ((link = ARKTableauList)) {
1788a381b04SJed Brown     ARKTableau t = &link->tab;
1798a381b04SJed Brown     ARKTableauList = link->next;
1808a381b04SJed Brown     ierr = PetscFree6(t->At,t->bt,t->ct,t->A,t->b,t->c);CHKERRQ(ierr);
181*cd652676SJed Brown     ierr = PetscFree2(t->binterpt,t->binterp);CHKERRQ(ierr);
1828a381b04SJed Brown     ierr = PetscFree(t->name);CHKERRQ(ierr);
1838a381b04SJed Brown     ierr = PetscFree(link);CHKERRQ(ierr);
1848a381b04SJed Brown   }
1858a381b04SJed Brown   TSARKIMEXRegisterAllCalled = PETSC_FALSE;
1868a381b04SJed Brown   PetscFunctionReturn(0);
1878a381b04SJed Brown }
1888a381b04SJed Brown 
1898a381b04SJed Brown #undef __FUNCT__
1908a381b04SJed Brown #define __FUNCT__ "TSARKIMEXInitializePackage"
1918a381b04SJed Brown /*@C
1928a381b04SJed Brown   TSARKIMEXInitializePackage - This function initializes everything in the TSARKIMEX package. It is called
1938a381b04SJed Brown   from PetscDLLibraryRegister() when using dynamic libraries, and on the first call to TSCreate_ARKIMEX()
1948a381b04SJed Brown   when using static libraries.
1958a381b04SJed Brown 
1968a381b04SJed Brown   Input Parameter:
1978a381b04SJed Brown   path - The dynamic library path, or PETSC_NULL
1988a381b04SJed Brown 
1998a381b04SJed Brown   Level: developer
2008a381b04SJed Brown 
2018a381b04SJed Brown .keywords: TS, TSARKIMEX, initialize, package
2028a381b04SJed Brown .seealso: PetscInitialize()
2038a381b04SJed Brown @*/
2048a381b04SJed Brown PetscErrorCode TSARKIMEXInitializePackage(const char path[])
2058a381b04SJed Brown {
2068a381b04SJed Brown   PetscErrorCode ierr;
2078a381b04SJed Brown 
2088a381b04SJed Brown   PetscFunctionBegin;
2098a381b04SJed Brown   if (TSARKIMEXPackageInitialized) PetscFunctionReturn(0);
2108a381b04SJed Brown   TSARKIMEXPackageInitialized = PETSC_TRUE;
2118a381b04SJed Brown   ierr = TSARKIMEXRegisterAll();CHKERRQ(ierr);
2128a381b04SJed Brown   ierr = PetscRegisterFinalize(TSARKIMEXFinalizePackage);CHKERRQ(ierr);
2138a381b04SJed Brown   PetscFunctionReturn(0);
2148a381b04SJed Brown }
2158a381b04SJed Brown 
2168a381b04SJed Brown #undef __FUNCT__
2178a381b04SJed Brown #define __FUNCT__ "TSARKIMEXFinalizePackage"
2188a381b04SJed Brown /*@C
2198a381b04SJed Brown   TSARKIMEXFinalizePackage - This function destroys everything in the TSARKIMEX package. It is
2208a381b04SJed Brown   called from PetscFinalize().
2218a381b04SJed Brown 
2228a381b04SJed Brown   Level: developer
2238a381b04SJed Brown 
2248a381b04SJed Brown .keywords: Petsc, destroy, package
2258a381b04SJed Brown .seealso: PetscFinalize()
2268a381b04SJed Brown @*/
2278a381b04SJed Brown PetscErrorCode TSARKIMEXFinalizePackage(void)
2288a381b04SJed Brown {
2298a381b04SJed Brown   PetscErrorCode ierr;
2308a381b04SJed Brown 
2318a381b04SJed Brown   PetscFunctionBegin;
2328a381b04SJed Brown   TSARKIMEXPackageInitialized = PETSC_FALSE;
2338a381b04SJed Brown   ierr = TSARKIMEXRegisterDestroy();CHKERRQ(ierr);
2348a381b04SJed Brown   PetscFunctionReturn(0);
2358a381b04SJed Brown }
2368a381b04SJed Brown 
2378a381b04SJed Brown #undef __FUNCT__
2388a381b04SJed Brown #define __FUNCT__ "TSARKIMEXRegister"
239*cd652676SJed Brown /*@C
240*cd652676SJed Brown    TSARKIMEXRegister - register an ARK IMEX scheme by providing the entries in the Butcher tableau and optionally embedded approximations and interpolation
241*cd652676SJed Brown 
242*cd652676SJed Brown    Not Collective, but the same schemes should be registered on all processes on which they will be used
243*cd652676SJed Brown 
244*cd652676SJed Brown    Input Parameters:
245*cd652676SJed Brown +  name - identifier for method
246*cd652676SJed Brown .  order - approximation order of method
247*cd652676SJed Brown .  s - number of stages, this is the dimension of the matrices below
248*cd652676SJed Brown .  At - Butcher table of stage coefficients for stiff part (dimension s*s, row-major)
249*cd652676SJed Brown .  bt - Butcher table for completing the stiff part of the step (dimension s; PETSC_NULL to use the last row of At)
250*cd652676SJed Brown .  ct - Abscissa of each stiff stage (dimension s, PETSC_NULL to use row sums of At)
251*cd652676SJed Brown .  A - Non-stiff stage coefficients (dimension s*s, row-major)
252*cd652676SJed Brown .  b - Non-stiff step completion table (dimension s; PETSC_NULL to use last row of At)
253*cd652676SJed Brown .  c - Non-stiff abscissa (dimension s; PETSC_NULL to use row sums of A)
254*cd652676SJed Brown .  pinterp - Order of the interpolation scheme, equal to the number of columns of binterpt and binterp
255*cd652676SJed Brown .  binterpt - Coefficients of the interpolation formula for the stiff part (dimension s*pinterp)
256*cd652676SJed Brown -  binterp - Coefficients of the interpolation formula for the non-stiff part (dimension s*pinterp; PETSC_NULL to reuse binterpt)
257*cd652676SJed Brown 
258*cd652676SJed Brown    Notes:
259*cd652676SJed Brown    Several ARK IMEX methods are provided, this function is only needed to create new methods.
260*cd652676SJed Brown 
261*cd652676SJed Brown    Level: advanced
262*cd652676SJed Brown 
263*cd652676SJed Brown .keywords: TS, register
264*cd652676SJed Brown 
265*cd652676SJed Brown .seealso: TSARKIMEX
266*cd652676SJed Brown @*/
2678a381b04SJed Brown PetscErrorCode TSARKIMEXRegister(const TSARKIMEXType name,PetscInt order,PetscInt s,
2688a381b04SJed Brown                                  const PetscReal At[],const PetscReal bt[],const PetscReal ct[],
269*cd652676SJed Brown                                  const PetscReal A[],const PetscReal b[],const PetscReal c[],
270*cd652676SJed Brown                                  PetscInt pinterp,const PetscReal binterpt[],const PetscReal binterp[])
2718a381b04SJed Brown {
2728a381b04SJed Brown   PetscErrorCode ierr;
2738a381b04SJed Brown   ARKTableauLink link;
2748a381b04SJed Brown   ARKTableau t;
2758a381b04SJed Brown   PetscInt i,j;
2768a381b04SJed Brown 
2778a381b04SJed Brown   PetscFunctionBegin;
2788a381b04SJed Brown   ierr = PetscMalloc(sizeof(*link),&link);CHKERRQ(ierr);
279*cd652676SJed Brown   ierr = PetscMemzero(link,sizeof(*link));CHKERRQ(ierr);
2808a381b04SJed Brown   t = &link->tab;
2818a381b04SJed Brown   ierr = PetscStrallocpy(name,&t->name);CHKERRQ(ierr);
2828a381b04SJed Brown   t->order = order;
2838a381b04SJed Brown   t->s = s;
2848a381b04SJed 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);
2858a381b04SJed Brown   ierr = PetscMemcpy(t->At,At,s*s*sizeof(At[0]));CHKERRQ(ierr);
2868a381b04SJed Brown   ierr = PetscMemcpy(t->A,A,s*s*sizeof(A[0]));CHKERRQ(ierr);
2878a381b04SJed Brown   if (bt) {ierr = PetscMemcpy(t->bt,bt,s*sizeof(bt[0]));CHKERRQ(ierr);}
2888a381b04SJed Brown   else for (i=0; i<s; i++) t->bt[i] = At[(s-1)*s+i];
2898a381b04SJed Brown   if (b) {ierr = PetscMemcpy(t->b,b,s*sizeof(b[0]));CHKERRQ(ierr);}
2908a381b04SJed Brown   else for (i=0; i<s; i++) t->b[i] = At[(s-1)*s+i];
2918a381b04SJed Brown   if (ct) {ierr = PetscMemcpy(t->ct,ct,s*sizeof(ct[0]));CHKERRQ(ierr);}
2928a381b04SJed 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];
2938a381b04SJed Brown   if (c) {ierr = PetscMemcpy(t->c,c,s*sizeof(c[0]));CHKERRQ(ierr);}
2948a381b04SJed 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];
295*cd652676SJed Brown   ierr = PetscMalloc2(s*pinterp,PetscReal,&t->binterpt,s*pinterp,PetscReal,&t->binterp);CHKERRQ(ierr);
296*cd652676SJed Brown   ierr = PetscMemcpy(t->binterpt,binterpt,s*pinterp*sizeof(binterpt[0]));CHKERRQ(ierr);
297*cd652676SJed Brown   ierr = PetscMemcpy(t->binterp,binterp?binterp:binterpt,s*pinterp*sizeof(binterpt[0]));CHKERRQ(ierr);
2988a381b04SJed Brown   link->next = ARKTableauList;
2998a381b04SJed Brown   ARKTableauList = link;
3008a381b04SJed Brown   PetscFunctionReturn(0);
3018a381b04SJed Brown }
3028a381b04SJed Brown 
3038a381b04SJed Brown #undef __FUNCT__
3048a381b04SJed Brown #define __FUNCT__ "TSStep_ARKIMEX"
3058a381b04SJed Brown static PetscErrorCode TSStep_ARKIMEX(TS ts)
3068a381b04SJed Brown {
3078a381b04SJed Brown   TS_ARKIMEX      *ark = (TS_ARKIMEX*)ts->data;
3088a381b04SJed Brown   ARKTableau      tab  = ark->tableau;
3098a381b04SJed Brown   const PetscInt  s    = tab->s;
3108a381b04SJed Brown   const PetscReal *At  = tab->At,*A = tab->A,*bt = tab->bt,*b = tab->b,*ct = tab->ct,*c = tab->c;
311406d0ec2SJed Brown   PetscScalar     *w   = ark->work;
3128a381b04SJed Brown   Vec             *Y   = ark->Y,*YdotI = ark->YdotI,*YdotRHS = ark->YdotRHS,Ydot = ark->Ydot,W = ark->Work,Z = ark->Z;
3138a381b04SJed Brown   SNES            snes;
3148a381b04SJed Brown   PetscInt        i,j,its,lits;
3158a381b04SJed Brown   PetscReal       h,t;
3168a381b04SJed Brown   PetscErrorCode  ierr;
3178a381b04SJed Brown 
3188a381b04SJed Brown   PetscFunctionBegin;
3198a381b04SJed Brown   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
3208a381b04SJed Brown   h = ts->time_step = ts->next_time_step;
3218a381b04SJed Brown   t = ts->ptime;
3228a381b04SJed Brown 
3238a381b04SJed Brown   for (i=0; i<s; i++) {
3248a381b04SJed Brown     if (At[i*s+i] == 0) {           /* This stage is explicit */
3258a381b04SJed Brown       ierr = VecCopy(ts->vec_sol,Y[i]);CHKERRQ(ierr);
3268a381b04SJed Brown       for (j=0; j<i; j++) w[j] = -h*At[i*s+j];
3278a381b04SJed Brown       ierr = VecMAXPY(Y[i],i,w,YdotI);CHKERRQ(ierr);
3288a381b04SJed Brown       for (j=0; j<i; j++) w[j] = h*A[i*s+j];
3298a381b04SJed Brown       ierr = VecMAXPY(Y[i],i,w,YdotRHS);CHKERRQ(ierr);
3308a381b04SJed Brown     } else {
3318a381b04SJed Brown       ark->stage_time = t + h*ct[i];
3328a381b04SJed Brown       ark->shift = 1./(h*At[i*s+i]);
3338a381b04SJed Brown       /* Affine part */
3348a381b04SJed Brown       ierr = VecZeroEntries(W);CHKERRQ(ierr);
3358a381b04SJed Brown       for (j=0; j<i; j++) w[j] = h*A[i*s+j];
3368a381b04SJed Brown       ierr = VecMAXPY(W,i,w,YdotRHS);CHKERRQ(ierr);
3378a381b04SJed Brown       /* Ydot = shift*(Y-Z) */
3388a381b04SJed Brown       ierr = VecCopy(ts->vec_sol,Z);CHKERRQ(ierr);
3398a381b04SJed Brown       for (j=0; j<i; j++) w[j] = h*At[i*s+j];
3408a381b04SJed Brown       ierr = VecMAXPY(Z,i,w,YdotRHS);CHKERRQ(ierr);
3418a381b04SJed Brown       /* Initial guess taken from last stage */
3428a381b04SJed Brown       ierr = VecCopy(i>0?Y[i-1]:ts->vec_sol,Y[i]);CHKERRQ(ierr);
3438a381b04SJed Brown       ierr = SNESSolve(snes,W,Y[i]);CHKERRQ(ierr);
3448a381b04SJed Brown       ierr = SNESGetIterationNumber(snes,&its);CHKERRQ(ierr);
3458a381b04SJed Brown       ierr = SNESGetLinearSolveIterations(snes,&lits);CHKERRQ(ierr);
3468a381b04SJed Brown       ts->nonlinear_its += its; ts->linear_its += lits;
3478a381b04SJed Brown     }
3488a381b04SJed Brown     ierr = VecZeroEntries(Ydot);CHKERRQ(ierr);
3498a381b04SJed Brown     ierr = TSComputeIFunction(ts,t+h*ct[i],Y[i],Ydot,YdotI[i],PETSC_TRUE);CHKERRQ(ierr);
3508a381b04SJed Brown     ierr = TSComputeRHSFunction(ts,t+h*c[i],Y[i],YdotRHS[i]);CHKERRQ(ierr);
3518a381b04SJed Brown   }
352a17b68daSJed Brown   for (j=0; j<s; j++) w[j] = -h*bt[j];
3538a381b04SJed Brown   ierr = VecMAXPY(ts->vec_sol,s,w,YdotI);CHKERRQ(ierr);
3548a381b04SJed Brown   for (j=0; j<s; j++) w[j] = h*b[j];
3558a381b04SJed Brown   ierr = VecMAXPY(ts->vec_sol,s,w,YdotRHS);CHKERRQ(ierr);
3568a381b04SJed Brown 
3578a381b04SJed Brown   ts->ptime          += ts->time_step;
3588a381b04SJed Brown   ts->next_time_step  = ts->time_step;
3598a381b04SJed Brown   ts->steps++;
3608a381b04SJed Brown   PetscFunctionReturn(0);
3618a381b04SJed Brown }
3628a381b04SJed Brown 
363*cd652676SJed Brown #undef __FUNCT__
364*cd652676SJed Brown #define __FUNCT__ "TSInterpolate_ARKIMEX"
365*cd652676SJed Brown static PetscErrorCode TSInterpolate_ARKIMEX(TS ts,PetscReal itime,Vec X)
366*cd652676SJed Brown {
367*cd652676SJed Brown   TS_ARKIMEX *ark = (TS_ARKIMEX*)ts->data;
368*cd652676SJed Brown   PetscInt s = ark->tableau->s,i,j;
369*cd652676SJed Brown   PetscReal tt,t = (itime - ts->ptime)/ts->time_step - 1; /* In the interval [0,1] */
370*cd652676SJed Brown   PetscScalar *bt,*b;
371*cd652676SJed Brown   const PetscReal *Bt = ark->tableau->binterpt,*B = ark->tableau->binterp;
372*cd652676SJed Brown   PetscErrorCode ierr;
373*cd652676SJed Brown 
374*cd652676SJed Brown   PetscFunctionBegin;
375*cd652676SJed Brown   if (!Bt || !B) SETERRQ1(((PetscObject)ts)->comm,PETSC_ERR_SUP,"TSARKIMEX %s does not have an interpolation formula",ark->tableau->name);
376*cd652676SJed Brown   ierr = PetscMalloc2(s,PetscScalar,&bt,s,PetscScalar,&b);CHKERRQ(ierr);
377*cd652676SJed Brown   for (i=0; i<s; i++) bt[i] = b[i] = 0;
378*cd652676SJed Brown   for (j=0,tt=t; j<s; j++,tt*=t) {
379*cd652676SJed Brown     for (i=0; i<s; i++) {
380*cd652676SJed Brown       bt[i] += Bt[i*s+j] * tt;
381*cd652676SJed Brown       b[i]  += B[i*s+j] * tt;
382*cd652676SJed Brown     }
383*cd652676SJed Brown   }
384*cd652676SJed 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");
385*cd652676SJed Brown   ierr = VecCopy(ark->Y[0],X);CHKERRQ(ierr);
386*cd652676SJed Brown   ierr = VecMAXPY(X,s,bt,ark->YdotI);CHKERRQ(ierr);
387*cd652676SJed Brown   ierr = VecMAXPY(X,s,b,ark->YdotRHS);CHKERRQ(ierr);
388*cd652676SJed Brown   ierr = PetscFree2(bt,b);CHKERRQ(ierr);
389*cd652676SJed Brown   PetscFunctionReturn(0);
390*cd652676SJed Brown }
391*cd652676SJed Brown 
3928a381b04SJed Brown /*------------------------------------------------------------*/
3938a381b04SJed Brown #undef __FUNCT__
3948a381b04SJed Brown #define __FUNCT__ "TSReset_ARKIMEX"
3958a381b04SJed Brown static PetscErrorCode TSReset_ARKIMEX(TS ts)
3968a381b04SJed Brown {
3978a381b04SJed Brown   TS_ARKIMEX      *ark = (TS_ARKIMEX*)ts->data;
3988a381b04SJed Brown   PetscInt        s;
3998a381b04SJed Brown   PetscErrorCode  ierr;
4008a381b04SJed Brown 
4018a381b04SJed Brown   PetscFunctionBegin;
4028a381b04SJed Brown   if (!ark->tableau) PetscFunctionReturn(0);
4038a381b04SJed Brown    s = ark->tableau->s;
4048a381b04SJed Brown   ierr = VecDestroyVecs(s,&ark->Y);CHKERRQ(ierr);
4058a381b04SJed Brown   ierr = VecDestroyVecs(s,&ark->YdotI);CHKERRQ(ierr);
4068a381b04SJed Brown   ierr = VecDestroyVecs(s,&ark->YdotRHS);CHKERRQ(ierr);
4078a381b04SJed Brown   ierr = VecDestroy(&ark->Ydot);CHKERRQ(ierr);
4088a381b04SJed Brown   ierr = VecDestroy(&ark->Work);CHKERRQ(ierr);
4098a381b04SJed Brown   ierr = VecDestroy(&ark->Z);CHKERRQ(ierr);
4108a381b04SJed Brown   ierr = PetscFree(ark->work);CHKERRQ(ierr);
4118a381b04SJed Brown   PetscFunctionReturn(0);
4128a381b04SJed Brown }
4138a381b04SJed Brown 
4148a381b04SJed Brown #undef __FUNCT__
4158a381b04SJed Brown #define __FUNCT__ "TSDestroy_ARKIMEX"
4168a381b04SJed Brown static PetscErrorCode TSDestroy_ARKIMEX(TS ts)
4178a381b04SJed Brown {
4188a381b04SJed Brown   PetscErrorCode  ierr;
4198a381b04SJed Brown 
4208a381b04SJed Brown   PetscFunctionBegin;
4218a381b04SJed Brown   ierr = TSReset_ARKIMEX(ts);CHKERRQ(ierr);
4228a381b04SJed Brown   ierr = PetscFree(ts->data);CHKERRQ(ierr);
4238a381b04SJed Brown   ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSARKIMEXGetType_C","",PETSC_NULL);CHKERRQ(ierr);
4248a381b04SJed Brown   ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSARKIMEXSetType_C","",PETSC_NULL);CHKERRQ(ierr);
4258a381b04SJed Brown   PetscFunctionReturn(0);
4268a381b04SJed Brown }
4278a381b04SJed Brown 
4288a381b04SJed Brown /*
4298a381b04SJed Brown   This defines the nonlinear equation that is to be solved with SNES
4308a381b04SJed Brown   G(U) = F[t0+Theta*dt, U, (U-U0)*shift] = 0
4318a381b04SJed Brown */
4328a381b04SJed Brown #undef __FUNCT__
4338a381b04SJed Brown #define __FUNCT__ "SNESTSFormFunction_ARKIMEX"
4348a381b04SJed Brown static PetscErrorCode SNESTSFormFunction_ARKIMEX(SNES snes,Vec X,Vec F,TS ts)
4358a381b04SJed Brown {
4368a381b04SJed Brown   TS_ARKIMEX     *ark = (TS_ARKIMEX*)ts->data;
4378a381b04SJed Brown   PetscErrorCode ierr;
4388a381b04SJed Brown 
4398a381b04SJed Brown   PetscFunctionBegin;
4408a381b04SJed Brown   ierr = VecAXPBYPCZ(ark->Ydot,-ark->shift,ark->shift,0,ark->Z,X);CHKERRQ(ierr); /* Ydot = shift*(X-Z) */
44131f6fcc0SJed Brown   ierr = TSComputeIFunction(ts,ark->stage_time,X,ark->Ydot,F,PETSC_TRUE);CHKERRQ(ierr);
4428a381b04SJed Brown   PetscFunctionReturn(0);
4438a381b04SJed Brown }
4448a381b04SJed Brown 
4458a381b04SJed Brown #undef __FUNCT__
4468a381b04SJed Brown #define __FUNCT__ "SNESTSFormJacobian_ARKIMEX"
4478a381b04SJed Brown static PetscErrorCode SNESTSFormJacobian_ARKIMEX(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *str,TS ts)
4488a381b04SJed Brown {
4498a381b04SJed Brown   TS_ARKIMEX       *ark = (TS_ARKIMEX*)ts->data;
4508a381b04SJed Brown   PetscErrorCode ierr;
4518a381b04SJed Brown 
4528a381b04SJed Brown   PetscFunctionBegin;
4538a381b04SJed Brown   /* ark->Ydot has already been computed in SNESTSFormFunction_ARKIMEX (SNES guarantees this) */
4548a381b04SJed Brown   ierr = TSComputeIJacobian(ts,ark->stage_time,X,ark->Ydot,ark->shift,A,B,str,PETSC_TRUE);CHKERRQ(ierr);
4558a381b04SJed Brown   PetscFunctionReturn(0);
4568a381b04SJed Brown }
4578a381b04SJed Brown 
4588a381b04SJed Brown #undef __FUNCT__
4598a381b04SJed Brown #define __FUNCT__ "TSSetUp_ARKIMEX"
4608a381b04SJed Brown static PetscErrorCode TSSetUp_ARKIMEX(TS ts)
4618a381b04SJed Brown {
4628a381b04SJed Brown   TS_ARKIMEX     *ark = (TS_ARKIMEX*)ts->data;
4638a381b04SJed Brown   ARKTableau     tab  = ark->tableau;
4648a381b04SJed Brown   PetscInt       s = tab->s;
4658a381b04SJed Brown   PetscErrorCode ierr;
4668a381b04SJed Brown 
4678a381b04SJed Brown   PetscFunctionBegin;
4688a381b04SJed Brown   if (!ark->tableau) {
469e24355feSJed Brown     ierr = TSARKIMEXSetType(ts,TSARKIMEXDefault);CHKERRQ(ierr);
4708a381b04SJed Brown   }
4718a381b04SJed Brown   ierr = VecDuplicateVecs(ts->vec_sol,s,&ark->Y);CHKERRQ(ierr);
4728a381b04SJed Brown   ierr = VecDuplicateVecs(ts->vec_sol,s,&ark->YdotI);CHKERRQ(ierr);
4738a381b04SJed Brown   ierr = VecDuplicateVecs(ts->vec_sol,s,&ark->YdotRHS);CHKERRQ(ierr);
4748a381b04SJed Brown   ierr = VecDuplicate(ts->vec_sol,&ark->Ydot);CHKERRQ(ierr);
4758a381b04SJed Brown   ierr = VecDuplicate(ts->vec_sol,&ark->Work);CHKERRQ(ierr);
4768a381b04SJed Brown   ierr = VecDuplicate(ts->vec_sol,&ark->Z);CHKERRQ(ierr);
4778a381b04SJed Brown   ierr = PetscMalloc(s*sizeof(ark->work[0]),&ark->work);CHKERRQ(ierr);
4788a381b04SJed Brown   PetscFunctionReturn(0);
4798a381b04SJed Brown }
4808a381b04SJed Brown /*------------------------------------------------------------*/
4818a381b04SJed Brown 
4828a381b04SJed Brown #undef __FUNCT__
4838a381b04SJed Brown #define __FUNCT__ "TSSetFromOptions_ARKIMEX"
4848a381b04SJed Brown static PetscErrorCode TSSetFromOptions_ARKIMEX(TS ts)
4858a381b04SJed Brown {
4868a381b04SJed Brown   PetscErrorCode ierr;
4878a381b04SJed Brown   char           arktype[256];
4888a381b04SJed Brown 
4898a381b04SJed Brown   PetscFunctionBegin;
4908a381b04SJed Brown   ierr = PetscOptionsHead("ARKIMEX ODE solver options");CHKERRQ(ierr);
4918a381b04SJed Brown   {
4928a381b04SJed Brown     ARKTableauLink link;
4938a381b04SJed Brown     PetscInt count,choice;
4948a381b04SJed Brown     PetscBool flg;
4958a381b04SJed Brown     const char **namelist;
4968a381b04SJed Brown     ierr = PetscStrncpy(arktype,TSARKIMEXDefault,sizeof arktype);CHKERRQ(ierr);
4978a381b04SJed Brown     for (link=ARKTableauList,count=0; link; link=link->next,count++) ;
4988a381b04SJed Brown     ierr = PetscMalloc(count*sizeof(char*),&namelist);CHKERRQ(ierr);
4998a381b04SJed Brown     for (link=ARKTableauList,count=0; link; link=link->next,count++) namelist[count] = link->tab.name;
5008a381b04SJed Brown     ierr = PetscOptionsEList("-ts_arkimex_type","Family of ARK IMEX method","TSARKIMEXSetType",(const char*const*)namelist,count,arktype,&choice,&flg);CHKERRQ(ierr);
5018a381b04SJed Brown     ierr = TSARKIMEXSetType(ts,flg ? namelist[choice] : arktype);CHKERRQ(ierr);
5028a381b04SJed Brown     ierr = PetscFree(namelist);CHKERRQ(ierr);
5038a381b04SJed Brown   }
5048a381b04SJed Brown   ierr = PetscOptionsTail();CHKERRQ(ierr);
5058a381b04SJed Brown   PetscFunctionReturn(0);
5068a381b04SJed Brown }
5078a381b04SJed Brown 
5088a381b04SJed Brown #undef __FUNCT__
5098a381b04SJed Brown #define __FUNCT__ "PetscFormatRealArray"
5108a381b04SJed Brown static PetscErrorCode PetscFormatRealArray(char buf[],size_t len,const char *fmt,PetscInt n,const PetscReal x[])
5118a381b04SJed Brown {
5128a381b04SJed Brown   int i,left,count;
5138a381b04SJed Brown   char *p;
5148a381b04SJed Brown 
5158a381b04SJed Brown   PetscFunctionBegin;
5168a381b04SJed Brown   for (i=0,p=buf,left=(int)len; i<n; i++) {
5178a381b04SJed Brown     count = snprintf(p,left,fmt,x[i]);
5188a381b04SJed Brown     if (count < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"snprintf()");
5198a381b04SJed Brown     if (count >= left) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Insufficient space in buffer");
5208a381b04SJed Brown     left -= count;
5218a381b04SJed Brown     p += count;
5228a381b04SJed Brown     *p++ = ' ';
5238a381b04SJed Brown   }
5248a381b04SJed Brown   p[i ? 0 : -1] = 0;
5258a381b04SJed Brown   PetscFunctionReturn(0);
5268a381b04SJed Brown }
5278a381b04SJed Brown 
5288a381b04SJed Brown #undef __FUNCT__
5298a381b04SJed Brown #define __FUNCT__ "TSView_ARKIMEX"
5308a381b04SJed Brown static PetscErrorCode TSView_ARKIMEX(TS ts,PetscViewer viewer)
5318a381b04SJed Brown {
5328a381b04SJed Brown   TS_ARKIMEX     *ark = (TS_ARKIMEX*)ts->data;
5338a381b04SJed Brown   ARKTableau     tab = ark->tableau;
5348a381b04SJed Brown   PetscBool      iascii;
5358a381b04SJed Brown   PetscErrorCode ierr;
5368a381b04SJed Brown 
5378a381b04SJed Brown   PetscFunctionBegin;
5388a381b04SJed Brown   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
5398a381b04SJed Brown   if (iascii) {
5408a381b04SJed Brown     const TSARKIMEXType arktype;
5418a381b04SJed Brown     char buf[512];
5428a381b04SJed Brown     ierr = TSARKIMEXGetType(ts,&arktype);CHKERRQ(ierr);
5438a381b04SJed Brown     ierr = PetscViewerASCIIPrintf(viewer,"  ARK IMEX %s\n",arktype);CHKERRQ(ierr);
5448a381b04SJed Brown     ierr = PetscFormatRealArray(buf,sizeof buf,"% 8.6f",tab->s,tab->ct);CHKERRQ(ierr);
54531f6fcc0SJed Brown     ierr = PetscViewerASCIIPrintf(viewer,"  Stiff abscissa       ct = %s\n",buf);CHKERRQ(ierr);
54631f6fcc0SJed Brown     ierr = PetscFormatRealArray(buf,sizeof buf,"% 8.6f",tab->s,tab->c);CHKERRQ(ierr);
54731f6fcc0SJed Brown     ierr = PetscViewerASCIIPrintf(viewer,"  Nonstiff abscissa     c = %s\n",buf);CHKERRQ(ierr);
5488a381b04SJed Brown   }
5498a381b04SJed Brown   PetscFunctionReturn(0);
5508a381b04SJed Brown }
5518a381b04SJed Brown 
5528a381b04SJed Brown #undef __FUNCT__
5538a381b04SJed Brown #define __FUNCT__ "TSARKIMEXSetType"
5548a381b04SJed Brown /*@C
5558a381b04SJed Brown   TSARKIMEXSetType - Set the type of ARK IMEX scheme
5568a381b04SJed Brown 
5578a381b04SJed Brown   Logically collective
5588a381b04SJed Brown 
5598a381b04SJed Brown   Input Parameter:
5608a381b04SJed Brown +  ts - timestepping context
5618a381b04SJed Brown -  arktype - type of ARK-IMEX scheme
5628a381b04SJed Brown 
5638a381b04SJed Brown   Level: intermediate
5648a381b04SJed Brown 
5658a381b04SJed Brown .seealso: TSARKIMEXGetType()
5668a381b04SJed Brown @*/
5678a381b04SJed Brown PetscErrorCode TSARKIMEXSetType(TS ts,const TSARKIMEXType arktype)
5688a381b04SJed Brown {
5698a381b04SJed Brown   PetscErrorCode ierr;
5708a381b04SJed Brown 
5718a381b04SJed Brown   PetscFunctionBegin;
5728a381b04SJed Brown   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5738a381b04SJed Brown   ierr = PetscTryMethod(ts,"TSARKIMEXSetType_C",(TS,const TSARKIMEXType),(ts,arktype));CHKERRQ(ierr);
5748a381b04SJed Brown   PetscFunctionReturn(0);
5758a381b04SJed Brown }
5768a381b04SJed Brown 
5778a381b04SJed Brown #undef __FUNCT__
5788a381b04SJed Brown #define __FUNCT__ "TSARKIMEXGetType"
5798a381b04SJed Brown /*@C
5808a381b04SJed Brown   TSARKIMEXGetType - Get the type of ARK IMEX scheme
5818a381b04SJed Brown 
5828a381b04SJed Brown   Logically collective
5838a381b04SJed Brown 
5848a381b04SJed Brown   Input Parameter:
5858a381b04SJed Brown .  ts - timestepping context
5868a381b04SJed Brown 
5878a381b04SJed Brown   Output Parameter:
5888a381b04SJed Brown .  arktype - type of ARK-IMEX scheme
5898a381b04SJed Brown 
5908a381b04SJed Brown   Level: intermediate
5918a381b04SJed Brown 
5928a381b04SJed Brown .seealso: TSARKIMEXGetType()
5938a381b04SJed Brown @*/
5948a381b04SJed Brown PetscErrorCode TSARKIMEXGetType(TS ts,const TSARKIMEXType *arktype)
5958a381b04SJed Brown {
5968a381b04SJed Brown   PetscErrorCode ierr;
5978a381b04SJed Brown 
5988a381b04SJed Brown   PetscFunctionBegin;
5998a381b04SJed Brown   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
6008a381b04SJed Brown   ierr = PetscUseMethod(ts,"TSARKIMEXGetType_C",(TS,const TSARKIMEXType*),(ts,arktype));CHKERRQ(ierr);
6018a381b04SJed Brown   PetscFunctionReturn(0);
6028a381b04SJed Brown }
6038a381b04SJed Brown 
6048a381b04SJed Brown EXTERN_C_BEGIN
6058a381b04SJed Brown #undef __FUNCT__
6068a381b04SJed Brown #define __FUNCT__ "TSARKIMEXGetType_ARKIMEX"
6078a381b04SJed Brown PetscErrorCode  TSARKIMEXGetType_ARKIMEX(TS ts,const TSARKIMEXType *arktype)
6088a381b04SJed Brown {
6098a381b04SJed Brown   TS_ARKIMEX *ark = (TS_ARKIMEX*)ts->data;
6108a381b04SJed Brown   PetscErrorCode ierr;
6118a381b04SJed Brown 
6128a381b04SJed Brown   PetscFunctionBegin;
6138a381b04SJed Brown   if (!ark->tableau) {ierr = TSARKIMEXSetType(ts,TSARKIMEXDefault);CHKERRQ(ierr);}
6148a381b04SJed Brown   *arktype = ark->tableau->name;
6158a381b04SJed Brown   PetscFunctionReturn(0);
6168a381b04SJed Brown }
6178a381b04SJed Brown #undef __FUNCT__
6188a381b04SJed Brown #define __FUNCT__ "TSARKIMEXSetType_ARKIMEX"
6198a381b04SJed Brown PetscErrorCode  TSARKIMEXSetType_ARKIMEX(TS ts,const TSARKIMEXType arktype)
6208a381b04SJed Brown {
6218a381b04SJed Brown   TS_ARKIMEX *ark = (TS_ARKIMEX*)ts->data;
6228a381b04SJed Brown   PetscErrorCode ierr;
6238a381b04SJed Brown   PetscBool match;
6248a381b04SJed Brown   ARKTableauLink link;
6258a381b04SJed Brown 
6268a381b04SJed Brown   PetscFunctionBegin;
6278a381b04SJed Brown   if (ark->tableau) {
6288a381b04SJed Brown     ierr = PetscStrcmp(ark->tableau->name,arktype,&match);CHKERRQ(ierr);
6298a381b04SJed Brown     if (match) PetscFunctionReturn(0);
6308a381b04SJed Brown   }
6318a381b04SJed Brown   for (link = ARKTableauList; link; link=link->next) {
6328a381b04SJed Brown     ierr = PetscStrcmp(link->tab.name,arktype,&match);CHKERRQ(ierr);
6338a381b04SJed Brown     if (match) {
6348a381b04SJed Brown       ierr = TSReset_ARKIMEX(ts);CHKERRQ(ierr);
6358a381b04SJed Brown       ark->tableau = &link->tab;
6368a381b04SJed Brown       PetscFunctionReturn(0);
6378a381b04SJed Brown     }
6388a381b04SJed Brown   }
6398a381b04SJed Brown   SETERRQ1(((PetscObject)ts)->comm,PETSC_ERR_ARG_UNKNOWN_TYPE,"Could not find '%s'",arktype);
6408a381b04SJed Brown   PetscFunctionReturn(0);
6418a381b04SJed Brown }
6428a381b04SJed Brown EXTERN_C_END
6438a381b04SJed Brown 
6448a381b04SJed Brown /* ------------------------------------------------------------ */
6458a381b04SJed Brown /*MC
6468a381b04SJed Brown       TSARKIMEX - ODE solver using Additive Runge-Kutta IMEX schemes
6478a381b04SJed Brown 
648fca742c7SJed Brown   These methods are intended for problems with well-separated time scales, especially when a slow scale is strongly
649fca742c7SJed Brown   nonlinear such that it is expensive to solve with a fully implicit method. The user should provide the stiff part
650fca742c7SJed Brown   of the equation using TSSetIFunction() and the non-stiff part with TSSetRHSFunction().
651fca742c7SJed Brown 
652fca742c7SJed Brown   Notes:
653fca742c7SJed Brown   This method currently only works with ODE, for which the stiff part G(t,X,Xdot) has the form Xdot + Ghat(t,X).
654fca742c7SJed Brown 
6558a381b04SJed Brown   Level: beginner
6568a381b04SJed Brown 
657fca742c7SJed Brown .seealso:  TSCreate(), TS, TSSetType(), TSARKIMEXRegister()
6588a381b04SJed Brown 
6598a381b04SJed Brown M*/
6608a381b04SJed Brown EXTERN_C_BEGIN
6618a381b04SJed Brown #undef __FUNCT__
6628a381b04SJed Brown #define __FUNCT__ "TSCreate_ARKIMEX"
6638a381b04SJed Brown PetscErrorCode  TSCreate_ARKIMEX(TS ts)
6648a381b04SJed Brown {
6658a381b04SJed Brown   TS_ARKIMEX       *th;
6668a381b04SJed Brown   PetscErrorCode ierr;
6678a381b04SJed Brown 
6688a381b04SJed Brown   PetscFunctionBegin;
6698a381b04SJed Brown #if !defined(PETSC_USE_DYNAMIC_LIBRARIES)
6708a381b04SJed Brown   ierr = TSARKIMEXInitializePackage(PETSC_NULL);CHKERRQ(ierr);
6718a381b04SJed Brown #endif
6728a381b04SJed Brown 
6738a381b04SJed Brown   ts->ops->reset          = TSReset_ARKIMEX;
6748a381b04SJed Brown   ts->ops->destroy        = TSDestroy_ARKIMEX;
6758a381b04SJed Brown   ts->ops->view           = TSView_ARKIMEX;
6768a381b04SJed Brown   ts->ops->setup          = TSSetUp_ARKIMEX;
6778a381b04SJed Brown   ts->ops->step           = TSStep_ARKIMEX;
678*cd652676SJed Brown   ts->ops->interpolate    = TSInterpolate_ARKIMEX;
6798a381b04SJed Brown   ts->ops->setfromoptions = TSSetFromOptions_ARKIMEX;
6808a381b04SJed Brown   ts->ops->snesfunction   = SNESTSFormFunction_ARKIMEX;
6818a381b04SJed Brown   ts->ops->snesjacobian   = SNESTSFormJacobian_ARKIMEX;
6828a381b04SJed Brown 
6838a381b04SJed Brown   ierr = PetscNewLog(ts,TS_ARKIMEX,&th);CHKERRQ(ierr);
6848a381b04SJed Brown   ts->data = (void*)th;
6858a381b04SJed Brown 
6868a381b04SJed Brown   ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSARKIMEXGetType_C","TSARKIMEXGetType_ARKIMEX",TSARKIMEXGetType_ARKIMEX);CHKERRQ(ierr);
6878a381b04SJed Brown   ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSARKIMEXSetType_C","TSARKIMEXSetType_ARKIMEX",TSARKIMEXSetType_ARKIMEX);CHKERRQ(ierr);
6888a381b04SJed Brown   PetscFunctionReturn(0);
6898a381b04SJed Brown }
6908a381b04SJed Brown EXTERN_C_END
691