xref: /petsc/src/ts/impls/arkimex/arkimex.c (revision 4040e9f2de29372b9e7b2414d75324058bbee0f6)
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 */
25cd652676SJed 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}};
76cd652676SJed 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},
85cd652676SJed Brown                   {1/(2*s2),1/(2*s2),1-1/s2}},
86cd652676SJed Brown       binterpt[3][2] = {{1,-0.5},{0,0},{0,0.5}};
87cd652676SJed 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},
92*4040e9f2SJed Brown                  {1767732205903./2027836641118.,0,0,0},
93*4040e9f2SJed Brown                  {5535828885825./10492691773637.,788022342437./10882634858940.,0,0},
94*4040e9f2SJed Brown                  {6485989280629./16251701735622.,-4246266847089./9704473918619.,10755448449292./10357097424841.,0}},
95a3a57f36SJed Brown       At[4][4] = {{0,0,0,0},
96*4040e9f2SJed Brown                   {1767732205903./4055673282236.,1767732205903./4055673282236.,0,0},
97*4040e9f2SJed Brown                   {2746238789719./10658868560708.,-640167445237./6845629431997.,1767732205903./4055673282236.,0},
98*4040e9f2SJed Brown                   {1471266399579./7840856788654.,-4482444167858./7529755066697.,11266239266428./11593286722821.,1767732205903./4055673282236.}},
99*4040e9f2SJed Brown       binterpt[4][2] = {{4655552711362./22874653954995., -215264564351./13552729205753.},
100*4040e9f2SJed Brown                         {-18682724506714./9892148508045.,17870216137069./13817060693119.},
101*4040e9f2SJed Brown                         {34259539580243./13192909600954.,-28141676662227./17317692491321.},
102*4040e9f2SJed Brown                         {584795268549./6622622206610.,   2508943948391./7218656332882.}};
103cd652676SJed 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},
109*4040e9f2SJed Brown                  {13861./62500.,6889./62500.,0,0,0,0},
110*4040e9f2SJed Brown                  {-116923316275./2393684061468.,-2731218467317./15368042101831.,9408046702089./11113171139209.,0,0,0},
111*4040e9f2SJed Brown                  {-451086348788./2902428689909.,-2682348792572./7519795681897.,12662868775082./11960479115383.,3355817975965./11060851509271.,0,0},
112*4040e9f2SJed 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},
115*4040e9f2SJed Brown                   {8611./62500.,-1743./31250.,1./4,0,0,0},
116*4040e9f2SJed Brown                   {5012029./34652500.,-654441./2922500.,174375./388108.,1./4,0,0},
117*4040e9f2SJed Brown                   {15267082809./155376265600.,-71443401./120774400.,730878875./902184768.,2285395./8070912.,1./4,0},
118*4040e9f2SJed Brown                   {82889./524892.,0,15625./83664.,69875./102672.,-2260./8211,1./4}},
119*4040e9f2SJed Brown       binterpt[6][3] = {{6943876665148./7220017795957.,-54480133./30881146.,6818779379841./7100303317025.},
120cd652676SJed Brown                         {0,0,0},
121*4040e9f2SJed Brown                         {7640104374378./9702883013639.,-11436875./14766696.,2173542590792./12501825683035.},
122*4040e9f2SJed Brown                         {-20649996744609./7521556579894.,174696575./18121608.,-31592104683404./5083833661969.},
123*4040e9f2SJed Brown                         {8854892464581./2390941311638.,-12120380./966161.,61146701046299./7138195549469.},
124*4040e9f2SJed Brown                         {-11397109935349./6675773540249.,3843./706.,-17219254887155./4939391667607.}};
125cd652676SJed 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},
131*4040e9f2SJed Brown                  {367902744464./2072280473677.,677623207551./8224143866563.,0,0,0,0,0,0},
132*4040e9f2SJed Brown                  {1268023523408./10340822734521.,0,1029933939417./13636558850479.,0,0,0,0,0},
133*4040e9f2SJed Brown                  {14463281900351./6315353703477.,0,66114435211212./5879490589093.,-54053170152839./4284798021562.,0,0,0,0},
134*4040e9f2SJed Brown                  {14090043504691./34967701212078.,0,15191511035443./11219624916014.,-18461159152457./12425892160975.,-281667163811./9011619295870.,0,0,0},
135*4040e9f2SJed Brown                  {19230459214898./13134317526959.,0,21275331358303./2942455364971.,-38145345988419./4862620318723.,-1./8,-1./8,0,0},
136*4040e9f2SJed 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},
138*4040e9f2SJed Brown                   {41./200.,41./200.,0,0,0,0,0,0},
139*4040e9f2SJed Brown                   {41./400.,-567603406766./11931857230679.,41./200.,0,0,0,0,0},
140*4040e9f2SJed Brown                   {683785636431./9252920307686.,0,-110385047103./1367015193373.,41./200.,0,0,0,0},
141*4040e9f2SJed Brown                   {3016520224154./10081342136671.,0,30586259806659./12414158314087.,-22760509404356./11113319521817.,41./200.,0,0,0},
142*4040e9f2SJed Brown                   {218866479029./1489978393911.,0,638256894668./5436446318841.,-1179710474555./5321154724896.,-60928119172./8023461067671.,41./200.,0,0},
143*4040e9f2SJed Brown                   {1020004230633./5715676835656.,0,25762820946817./25263940353407.,-2161375909145./9755907335909.,-211217309593./5846859502534.,-4269925059573./7827059040749.,41./200,0},
144*4040e9f2SJed Brown                   {-872700587467./9133579230613.,0,0,22348218063261./9555858737531.,-1143369518992./8141816002931.,-39379526789629./19018526304540.,32727382324388./42900044865799.,41./200.}},
145*4040e9f2SJed Brown       binterpt[8][3] = {{-17674230611817./10670229744614. ,  43486358583215./12773830924787. , -9257016797708./5021505065439.},
146cd652676SJed Brown                         {0                               ,  0                              , 0                            },
147cd652676SJed Brown                         {0                               ,  0                              , 0                            },
148*4040e9f2SJed Brown                         {65168852399939./7868540260826.  ,  -91478233927265./11067650958493., 26096422576131./11239449250142.},
149*4040e9f2SJed Brown                         {15494834004392./5936557850923.  ,  -79368583304911./10890268929626., 92396832856987./20362823103730.},
150*4040e9f2SJed Brown                         {-99329723586156./26959484932159.,  -12239297817655./9152339842473. , 30029262896817./10175596800299.},
151*4040e9f2SJed Brown                         {-19024464361622./5461577185407. ,  115839755401235./10719374521269., -26136350496073./3983972220547.},
152*4040e9f2SJed Brown                         {-6511271360970./6095937251113.  ,  5843115559534./2180450260947.   , -5289405421727./3760307252460. }};
153cd652676SJed 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);
181cd652676SJed 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"
239cd652676SJed Brown /*@C
240cd652676SJed Brown    TSARKIMEXRegister - register an ARK IMEX scheme by providing the entries in the Butcher tableau and optionally embedded approximations and interpolation
241cd652676SJed Brown 
242cd652676SJed Brown    Not Collective, but the same schemes should be registered on all processes on which they will be used
243cd652676SJed Brown 
244cd652676SJed Brown    Input Parameters:
245cd652676SJed Brown +  name - identifier for method
246cd652676SJed Brown .  order - approximation order of method
247cd652676SJed Brown .  s - number of stages, this is the dimension of the matrices below
248cd652676SJed Brown .  At - Butcher table of stage coefficients for stiff part (dimension s*s, row-major)
249cd652676SJed Brown .  bt - Butcher table for completing the stiff part of the step (dimension s; PETSC_NULL to use the last row of At)
250cd652676SJed Brown .  ct - Abscissa of each stiff stage (dimension s, PETSC_NULL to use row sums of At)
251cd652676SJed Brown .  A - Non-stiff stage coefficients (dimension s*s, row-major)
252cd652676SJed Brown .  b - Non-stiff step completion table (dimension s; PETSC_NULL to use last row of At)
253cd652676SJed Brown .  c - Non-stiff abscissa (dimension s; PETSC_NULL to use row sums of A)
254cd652676SJed Brown .  pinterp - Order of the interpolation scheme, equal to the number of columns of binterpt and binterp
255cd652676SJed Brown .  binterpt - Coefficients of the interpolation formula for the stiff part (dimension s*pinterp)
256cd652676SJed Brown -  binterp - Coefficients of the interpolation formula for the non-stiff part (dimension s*pinterp; PETSC_NULL to reuse binterpt)
257cd652676SJed Brown 
258cd652676SJed Brown    Notes:
259cd652676SJed Brown    Several ARK IMEX methods are provided, this function is only needed to create new methods.
260cd652676SJed Brown 
261cd652676SJed Brown    Level: advanced
262cd652676SJed Brown 
263cd652676SJed Brown .keywords: TS, register
264cd652676SJed Brown 
265cd652676SJed Brown .seealso: TSARKIMEX
266cd652676SJed Brown @*/
2678a381b04SJed Brown PetscErrorCode TSARKIMEXRegister(const TSARKIMEXType name,PetscInt order,PetscInt s,
2688a381b04SJed Brown                                  const PetscReal At[],const PetscReal bt[],const PetscReal ct[],
269cd652676SJed Brown                                  const PetscReal A[],const PetscReal b[],const PetscReal c[],
270cd652676SJed 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);
279cd652676SJed 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];
295cd652676SJed Brown   ierr = PetscMalloc2(s*pinterp,PetscReal,&t->binterpt,s*pinterp,PetscReal,&t->binterp);CHKERRQ(ierr);
296cd652676SJed Brown   ierr = PetscMemcpy(t->binterpt,binterpt,s*pinterp*sizeof(binterpt[0]));CHKERRQ(ierr);
297cd652676SJed 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 
363cd652676SJed Brown #undef __FUNCT__
364cd652676SJed Brown #define __FUNCT__ "TSInterpolate_ARKIMEX"
365cd652676SJed Brown static PetscErrorCode TSInterpolate_ARKIMEX(TS ts,PetscReal itime,Vec X)
366cd652676SJed Brown {
367cd652676SJed Brown   TS_ARKIMEX *ark = (TS_ARKIMEX*)ts->data;
368cd652676SJed Brown   PetscInt s = ark->tableau->s,i,j;
369cd652676SJed Brown   PetscReal tt,t = (itime - ts->ptime)/ts->time_step - 1; /* In the interval [0,1] */
370cd652676SJed Brown   PetscScalar *bt,*b;
371cd652676SJed Brown   const PetscReal *Bt = ark->tableau->binterpt,*B = ark->tableau->binterp;
372cd652676SJed Brown   PetscErrorCode ierr;
373cd652676SJed Brown 
374cd652676SJed Brown   PetscFunctionBegin;
375cd652676SJed Brown   if (!Bt || !B) SETERRQ1(((PetscObject)ts)->comm,PETSC_ERR_SUP,"TSARKIMEX %s does not have an interpolation formula",ark->tableau->name);
376cd652676SJed Brown   ierr = PetscMalloc2(s,PetscScalar,&bt,s,PetscScalar,&b);CHKERRQ(ierr);
377cd652676SJed Brown   for (i=0; i<s; i++) bt[i] = b[i] = 0;
378cd652676SJed Brown   for (j=0,tt=t; j<s; j++,tt*=t) {
379cd652676SJed Brown     for (i=0; i<s; i++) {
380cd652676SJed Brown       bt[i] += Bt[i*s+j] * tt;
381cd652676SJed Brown       b[i]  += B[i*s+j] * tt;
382cd652676SJed Brown     }
383cd652676SJed Brown   }
384cd652676SJed 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");
385cd652676SJed Brown   ierr = VecCopy(ark->Y[0],X);CHKERRQ(ierr);
386cd652676SJed Brown   ierr = VecMAXPY(X,s,bt,ark->YdotI);CHKERRQ(ierr);
387cd652676SJed Brown   ierr = VecMAXPY(X,s,b,ark->YdotRHS);CHKERRQ(ierr);
388cd652676SJed Brown   ierr = PetscFree2(bt,b);CHKERRQ(ierr);
389cd652676SJed Brown   PetscFunctionReturn(0);
390cd652676SJed Brown }
391cd652676SJed 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;
678cd652676SJed 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