xref: /petsc/src/ts/impls/arkimex/arkimex.c (revision cdb298fc07bf220cfdaacf66caf9947aa6170c77)
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 
7f9c1d6abSBarry Smith   F(t,U,Udot) = G(t,U)
88a381b04SJed Brown 
98a381b04SJed Brown   where F represents the stiff part of the physics and G represents the non-stiff part.
108a381b04SJed Brown 
118a381b04SJed Brown */
12b45d2f2cSJed Brown #include <petsc-private/tsimpl.h>                /*I   "petscts.h"   I*/
138a381b04SJed Brown 
1419fd82e9SBarry Smith static TSARKIMEXType TSARKIMEXDefault = TSARKIMEX3;
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;
214f385281SJed Brown   PetscInt  order;               /* Classical approximation order of the method */
224f385281SJed Brown   PetscInt  s;                   /* Number of stages */
234f385281SJed Brown   PetscInt  pinterp;             /* Interpolation order */
244f385281SJed Brown   PetscReal *At,*bt,*ct;        /* Stiff tableau */
258a381b04SJed Brown   PetscReal *A,*b,*c;           /* Non-stiff tableau */
26108c343cSJed Brown   PetscReal *bembedt,*bembed;   /* Embedded formula of order one less (order-1) */
27cd652676SJed Brown   PetscReal *binterpt,*binterp; /* Dense output formula */
28108c343cSJed Brown   PetscReal ccfl;               /* Placeholder for CFL coefficient relative to forward Euler */
298a381b04SJed Brown };
308a381b04SJed Brown typedef struct _ARKTableauLink *ARKTableauLink;
318a381b04SJed Brown struct _ARKTableauLink {
328a381b04SJed Brown   struct _ARKTableau tab;
338a381b04SJed Brown   ARKTableauLink next;
348a381b04SJed Brown };
358a381b04SJed Brown static ARKTableauLink ARKTableauList;
368a381b04SJed Brown 
378a381b04SJed Brown typedef struct {
388a381b04SJed Brown   ARKTableau   tableau;
398a381b04SJed Brown   Vec          *Y;               /* States computed during the step */
408a381b04SJed Brown   Vec          *YdotI;           /* Time derivatives for the stiff part */
418a381b04SJed Brown   Vec          *YdotRHS;         /* Function evaluations for the non-stiff part */
428a381b04SJed Brown   Vec          Ydot;             /* Work vector holding Ydot during residual evaluation */
438a381b04SJed Brown   Vec          Work;             /* Generic work vector */
448a381b04SJed Brown   Vec          Z;                /* Ydot = shift(Y-Z) */
458a381b04SJed Brown   PetscScalar  *work;            /* Scalar work */
46b296d7d5SJed Brown   PetscReal    scoeff;           /* shift = scoeff/dt */
478a381b04SJed Brown   PetscReal    stage_time;
484cc180ffSJed Brown   PetscBool    imex;
49108c343cSJed Brown   TSStepStatus status;
508a381b04SJed Brown } TS_ARKIMEX;
511f80e275SEmil Constantinescu /*MC
521f80e275SEmil Constantinescu      TSARKIMEXARS122 - Second order ARK IMEX scheme.
538a381b04SJed Brown 
541f80e275SEmil Constantinescu      This method has one explicit stage and one implicit stage.
551f80e275SEmil Constantinescu 
561f80e275SEmil Constantinescu      References:
571f80e275SEmil Constantinescu      U. Ascher, S. Ruuth, R. J. Spitheri, Implicit-explicit Runge-Kutta methods for time dependent Partial Differential Equations. Appl. Numer. Math. 25, (1997), pp. 151–167.
581f80e275SEmil Constantinescu 
591f80e275SEmil Constantinescu      Level: advanced
601f80e275SEmil Constantinescu 
611f80e275SEmil Constantinescu .seealso: TSARKIMEX
621f80e275SEmil Constantinescu M*/
631f80e275SEmil Constantinescu /*MC
641f80e275SEmil Constantinescu      TSARKIMEXA2 - Second order ARK IMEX scheme with A-stable implicit part.
651f80e275SEmil Constantinescu 
661f80e275SEmil Constantinescu      This method has an explicit stage and one implicit stage, and has an A-stable implicit scheme. This method was provided by Emil Constantinescu.
671f80e275SEmil Constantinescu 
681f80e275SEmil Constantinescu      Level: advanced
691f80e275SEmil Constantinescu 
701f80e275SEmil Constantinescu .seealso: TSARKIMEX
711f80e275SEmil Constantinescu M*/
721f80e275SEmil Constantinescu /*MC
731f80e275SEmil Constantinescu      TSARKIMEXL2 - Second order ARK IMEX scheme with L-stable implicit part.
741f80e275SEmil Constantinescu 
751f80e275SEmil Constantinescu      This method has two implicit stages, and L-stable implicit scheme.
761f80e275SEmil Constantinescu 
771f80e275SEmil Constantinescu     References:
781f80e275SEmil Constantinescu      L. Pareschi, G. Russo, Implicit-Explicit Runge-Kutta schemes and applications to hyperbolic systems with relaxations. Journal of Scientific Computing Volume: 25, Issue: 1, October, 2005, pp. 129-155
791f80e275SEmil Constantinescu 
801f80e275SEmil Constantinescu      Level: advanced
811f80e275SEmil Constantinescu 
821f80e275SEmil Constantinescu .seealso: TSARKIMEX
831f80e275SEmil Constantinescu M*/
841f80e275SEmil Constantinescu /*MC
851f80e275SEmil Constantinescu      TSARKIMEX2C - Second order ARK IMEX scheme with L-stable implicit part.
861f80e275SEmil Constantinescu 
871f80e275SEmil Constantinescu      This method has one explicit stage and two implicit stages. The implicit part is the same as in TSARKIMEX2D and TSARKIMEX2E, but the explicit part has a larger stability region on the negative real axis. This method was provided by Emil Constantinescu.
881f80e275SEmil Constantinescu 
891f80e275SEmil Constantinescu      Level: advanced
901f80e275SEmil Constantinescu 
911f80e275SEmil Constantinescu .seealso: TSARKIMEX
921f80e275SEmil Constantinescu M*/
9364f491ddSJed Brown /*MC
9464f491ddSJed Brown      TSARKIMEX2D - Second order ARK IMEX scheme with L-stable implicit part.
9564f491ddSJed Brown 
96617a39beSEmil Constantinescu      This method has one explicit stage and two implicit stages. The stability function is independent of the explicit part in the infinity limit of the implict component. This method was provided by Emil Constantinescu.
9764f491ddSJed Brown 
98b330ce4dSSatish Balay      Level: advanced
99b330ce4dSSatish Balay 
10064f491ddSJed Brown .seealso: TSARKIMEX
10164f491ddSJed Brown M*/
10264f491ddSJed Brown /*MC
10364f491ddSJed Brown      TSARKIMEX2E - Second order ARK IMEX scheme with L-stable implicit part.
10464f491ddSJed Brown 
10564f491ddSJed Brown      This method has one explicit stage and two implicit stages. It is is an optimal method developed by Emil Constantinescu.
10664f491ddSJed Brown 
107b330ce4dSSatish Balay      Level: advanced
108b330ce4dSSatish Balay 
10964f491ddSJed Brown .seealso: TSARKIMEX
11064f491ddSJed Brown M*/
11164f491ddSJed Brown /*MC
1126cf0794eSJed Brown      TSARKIMEXPRSSP2 - Second order SSP ARK IMEX scheme.
1136cf0794eSJed Brown 
1146cf0794eSJed Brown      This method has three implicit stages.
1156cf0794eSJed Brown 
1166cf0794eSJed Brown      References:
1176cf0794eSJed Brown      L. Pareschi, G. Russo, Implicit-Explicit Runge-Kutta schemes and applications to hyperbolic systems with relaxations. Journal of Scientific Computing Volume: 25, Issue: 1, October, 2005, pp. 129-155
1186cf0794eSJed Brown 
1196cf0794eSJed Brown      This method is referred to as SSP2-(3,3,2) in http://arxiv.org/abs/1110.4375
1206cf0794eSJed Brown 
1216cf0794eSJed Brown      Level: advanced
1226cf0794eSJed Brown 
1236cf0794eSJed Brown .seealso: TSARKIMEX
1246cf0794eSJed Brown M*/
1256cf0794eSJed Brown /*MC
12664f491ddSJed Brown      TSARKIMEX3 - Third order ARK IMEX scheme with L-stable implicit part.
12764f491ddSJed Brown 
12864f491ddSJed Brown      This method has one explicit stage and three implicit stages.
12964f491ddSJed Brown 
13064f491ddSJed Brown      References:
13164f491ddSJed Brown      Kennedy and Carpenter 2003.
13264f491ddSJed Brown 
133b330ce4dSSatish Balay      Level: advanced
134b330ce4dSSatish Balay 
13564f491ddSJed Brown .seealso: TSARKIMEX
13664f491ddSJed Brown M*/
13764f491ddSJed Brown /*MC
1386cf0794eSJed Brown      TSARKIMEXARS443 - Third order ARK IMEX scheme.
1396cf0794eSJed Brown 
1406cf0794eSJed Brown      This method has one explicit stage and four implicit stages.
1416cf0794eSJed Brown 
1426cf0794eSJed Brown      References:
1436cf0794eSJed Brown      U. Ascher, S. Ruuth, R. J. Spitheri, Implicit-explicit Runge-Kutta methods for time dependent Partial Differential Equations. Appl. Numer. Math. 25, (1997), pp. 151–167.
1446cf0794eSJed Brown 
1456cf0794eSJed Brown      This method is referred to as ARS(4,4,3) in http://arxiv.org/abs/1110.4375
1466cf0794eSJed Brown 
1476cf0794eSJed Brown      Level: advanced
1486cf0794eSJed Brown 
1496cf0794eSJed Brown .seealso: TSARKIMEX
1506cf0794eSJed Brown M*/
1516cf0794eSJed Brown /*MC
1526cf0794eSJed Brown      TSARKIMEXBPR3 - Third order ARK IMEX scheme.
1536cf0794eSJed Brown 
1546cf0794eSJed Brown      This method has one explicit stage and four implicit stages.
1556cf0794eSJed Brown 
1566cf0794eSJed Brown      References:
1576cf0794eSJed Brown      This method is referred to as ARK3 in http://arxiv.org/abs/1110.4375
1586cf0794eSJed Brown 
1596cf0794eSJed Brown      Level: advanced
1606cf0794eSJed Brown 
1616cf0794eSJed Brown .seealso: TSARKIMEX
1626cf0794eSJed Brown M*/
1636cf0794eSJed Brown /*MC
16464f491ddSJed Brown      TSARKIMEX4 - Fourth order ARK IMEX scheme with L-stable implicit part.
16564f491ddSJed Brown 
16664f491ddSJed Brown      This method has one explicit stage and four implicit stages.
16764f491ddSJed Brown 
16864f491ddSJed Brown      References:
16964f491ddSJed Brown      Kennedy and Carpenter 2003.
17064f491ddSJed Brown 
171b330ce4dSSatish Balay      Level: advanced
172b330ce4dSSatish Balay 
17364f491ddSJed Brown .seealso: TSARKIMEX
17464f491ddSJed Brown M*/
17564f491ddSJed Brown /*MC
17664f491ddSJed Brown      TSARKIMEX5 - Fifth order ARK IMEX scheme with L-stable implicit part.
17764f491ddSJed Brown 
17864f491ddSJed Brown      This method has one explicit stage and five implicit stages.
17964f491ddSJed Brown 
18064f491ddSJed Brown      References:
18164f491ddSJed Brown      Kennedy and Carpenter 2003.
18264f491ddSJed Brown 
183b330ce4dSSatish Balay      Level: advanced
184b330ce4dSSatish Balay 
18564f491ddSJed Brown .seealso: TSARKIMEX
18664f491ddSJed Brown M*/
18764f491ddSJed Brown 
1888a381b04SJed Brown #undef __FUNCT__
1898a381b04SJed Brown #define __FUNCT__ "TSARKIMEXRegisterAll"
1908a381b04SJed Brown /*@C
1918a381b04SJed Brown   TSARKIMEXRegisterAll - Registers all of the additive Runge-Kutta implicit-explicit methods in TSARKIMEX
1928a381b04SJed Brown 
193fca742c7SJed Brown   Not Collective, but should be called by all processes which will need the schemes to be registered
1948a381b04SJed Brown 
1958a381b04SJed Brown   Level: advanced
1968a381b04SJed Brown 
1978a381b04SJed Brown .keywords: TS, TSARKIMEX, register, all
1988a381b04SJed Brown 
1998a381b04SJed Brown .seealso:  TSARKIMEXRegisterDestroy()
2008a381b04SJed Brown @*/
2018a381b04SJed Brown PetscErrorCode TSARKIMEXRegisterAll(void)
2028a381b04SJed Brown {
2038a381b04SJed Brown   PetscErrorCode ierr;
2048a381b04SJed Brown 
2058a381b04SJed Brown   PetscFunctionBegin;
2068a381b04SJed Brown   if (TSARKIMEXRegisterAllCalled) PetscFunctionReturn(0);
2078a381b04SJed Brown   TSARKIMEXRegisterAllCalled = PETSC_TRUE;
2088a381b04SJed Brown   {
2098a381b04SJed Brown     const PetscReal
2101f80e275SEmil Constantinescu       A[2][2] = {{0.0,0.0},
2111f80e275SEmil Constantinescu                  {0.5,0.0}},
2121f80e275SEmil Constantinescu       At[2][2] = {{0.0,0.0},
2131f80e275SEmil Constantinescu                   {0.0,0.5}},
2141f80e275SEmil Constantinescu         b[2] = {0.0,1.0},
2151f80e275SEmil Constantinescu           bembedt[2] = {0.5,0.5};
2161f80e275SEmil Constantinescu           /* binterpt[2][2] = {{1.0,-1.0},{0.0,1.0}};  second order dense output has poor stability properties and hence it is not currently in use*/
2171f80e275SEmil Constantinescu           ierr = TSARKIMEXRegister(TSARKIMEXARS122,2,2,&At[0][0],b,PETSC_NULL,&A[0][0],b,PETSC_NULL,bembedt,bembedt,1,b,PETSC_NULL);CHKERRQ(ierr);
2181f80e275SEmil Constantinescu   }
2191f80e275SEmil Constantinescu   {
2201f80e275SEmil Constantinescu     const PetscReal
2211f80e275SEmil Constantinescu       A[2][2] = {{0.0,0.0},
2221f80e275SEmil Constantinescu                  {1.0,0.0}},
2231f80e275SEmil Constantinescu       At[2][2] = {{0.0,0.0},
2241f80e275SEmil Constantinescu                   {0.5,0.5}},
2251f80e275SEmil Constantinescu         b[2] = {0.5,0.5},
2261f80e275SEmil Constantinescu           bembedt[2] = {0.0,1.0};
2271f80e275SEmil Constantinescu           /* binterpt[2][2] = {{1.0,-0.5},{0.0,0.5}}  second order dense output has poor stability properties and hence it is not currently in use*/
2281f80e275SEmil Constantinescu           ierr = TSARKIMEXRegister(TSARKIMEXA2,2,2,&At[0][0],b,PETSC_NULL,&A[0][0],b,PETSC_NULL,bembedt,bembedt,1,b,PETSC_NULL);CHKERRQ(ierr);
2291f80e275SEmil Constantinescu   }
2301f80e275SEmil Constantinescu   {
2311f80e275SEmil Constantinescu     const PetscReal us2 = 1.0-1.0/PetscSqrtReal((PetscReal)2.0);
2321f80e275SEmil Constantinescu     const PetscReal
2331f80e275SEmil Constantinescu       A[2][2] = {{0.0,0.0},
2341f80e275SEmil Constantinescu                  {1.0,0.0}},
2351f80e275SEmil Constantinescu       At[2][2] = {{us2,0.0},
2361f80e275SEmil Constantinescu                   {1.0-2.0*us2,us2}},
2371f80e275SEmil Constantinescu         b[2] = {0.5,0.5},
2381f80e275SEmil Constantinescu           bembedt[2] = {0.0,1.0},
2391f80e275SEmil Constantinescu             binterpt[2][2] = {{(us2-1.0)/(2.0*us2-1.0),-1/(2.0*(1.0-2.0*us2))},{1-(us2-1.0)/(2.0*us2-1.0),-1/(2.0*(1.0-2.0*us2))}},
2401f80e275SEmil Constantinescu               binterp[2][2] = {{1.0,-0.5},{0.0,0.5}};
2411f80e275SEmil Constantinescu               ierr = TSARKIMEXRegister(TSARKIMEXL2,2,2,&At[0][0],b,PETSC_NULL,&A[0][0],b,PETSC_NULL,bembedt,bembedt,2,binterpt[0],binterp[0]);CHKERRQ(ierr);
2421f80e275SEmil Constantinescu   }
2431f80e275SEmil Constantinescu   {
2441f80e275SEmil Constantinescu     const PetscReal s2 = PetscSqrtReal((PetscReal)2.0),
2458a381b04SJed Brown       A[3][3] = {{0,0,0},
2461f80e275SEmil Constantinescu                  {2-s2,0,0},
247617a39beSEmil Constantinescu                  {0.5,0.5,0}},
2481f80e275SEmil Constantinescu       At[3][3] = {{0,0,0},
2491f80e275SEmil Constantinescu                   {1-1/s2,1-1/s2,0},
2501f80e275SEmil Constantinescu                   {1/(2*s2),1/(2*s2),1-1/s2}},
251e93ac1c2SEmil Constantinescu         bembedt[3] = {(4.-s2)/8.,(4.-s2)/8.,1/(2.*s2)},
252ce4a059fSEmil Constantinescu         binterpt[3][2] = {{1.0/s2,-1.0/(2.0*s2)},{1.0/s2,-1.0/(2.0*s2)},{1.0-s2,1.0/s2}};
2531f80e275SEmil Constantinescu     ierr = TSARKIMEXRegister(TSARKIMEX2C,2,3,&At[0][0],PETSC_NULL,PETSC_NULL,&A[0][0],PETSC_NULL,PETSC_NULL,bembedt,bembedt,2,binterpt[0],PETSC_NULL);CHKERRQ(ierr);
2541f80e275SEmil Constantinescu   }
2551f80e275SEmil Constantinescu   {
2561f80e275SEmil Constantinescu     const PetscReal s2 = PetscSqrtReal((PetscReal)2.0),
2571f80e275SEmil Constantinescu       A[3][3] = {{0,0,0},
2581f80e275SEmil Constantinescu                  {2-s2,0,0},
2598a381b04SJed Brown                  {0.75,0.25,0}},
2608a381b04SJed Brown       At[3][3] = {{0,0,0},
2611f80e275SEmil Constantinescu                   {1-1/s2,1-1/s2,0},
2621f80e275SEmil Constantinescu                   {1/(2*s2),1/(2*s2),1-1/s2}},
263e93ac1c2SEmil Constantinescu       bembedt[3] = {(4.-s2)/8.,(4.-s2)/8.,1/(2.*s2)},
264ce4a059fSEmil Constantinescu       binterpt[3][2] =  {{1.0/s2,-1.0/(2.0*s2)},{1.0/s2,-1.0/(2.0*s2)},{1.0-s2,1.0/s2}};
265108c343cSJed Brown       ierr = TSARKIMEXRegister(TSARKIMEX2D,2,3,&At[0][0],PETSC_NULL,PETSC_NULL,&A[0][0],PETSC_NULL,PETSC_NULL,bembedt,bembedt,2,binterpt[0],PETSC_NULL);CHKERRQ(ierr);
2668a381b04SJed Brown   }
26706db7b1cSJed Brown   {                             /* Optimal for linear implicit part */
26803403c7fSJed Brown     const PetscReal s2 = PetscSqrtReal((PetscReal)2.0),
269a3a57f36SJed Brown       A[3][3] = {{0,0,0},
270a3a57f36SJed Brown                  {2-s2,0,0},
271a3a57f36SJed Brown                  {(3-2*s2)/6,(3+2*s2)/6,0}},
272a3a57f36SJed Brown       At[3][3] = {{0,0,0},
273a3a57f36SJed Brown                   {1-1/s2,1-1/s2,0},
274cd652676SJed Brown                   {1/(2*s2),1/(2*s2),1-1/s2}},
275e93ac1c2SEmil Constantinescu       bembedt[3] = {(4.-s2)/8.,(4.-s2)/8.,1/(2.*s2)},
276ce4a059fSEmil Constantinescu       binterpt[3][2] =  {{1.0/s2,-1.0/(2.0*s2)},{1.0/s2,-1.0/(2.0*s2)},{1.0-s2,1.0/s2}};
2771f80e275SEmil Constantinescu     ierr = TSARKIMEXRegister(TSARKIMEX2E,2,3,&At[0][0],PETSC_NULL,PETSC_NULL,&A[0][0],PETSC_NULL,PETSC_NULL,bembedt,bembedt,2,binterpt[0],PETSC_NULL);CHKERRQ(ierr);
278a3a57f36SJed Brown   }
2796cf0794eSJed Brown   {                             /* Optimal for linear implicit part */
2806cf0794eSJed Brown     const PetscReal
2816cf0794eSJed Brown       A[3][3] = {{0,0,0},
2826cf0794eSJed Brown                  {0.5,0,0},
2836cf0794eSJed Brown                  {0.5,0.5,0}},
2846cf0794eSJed Brown       At[3][3] = {{0.25,0,0},
2856cf0794eSJed Brown                   {0,0.25,0},
2866cf0794eSJed Brown                   {1./3,1./3,1./3}};
287108c343cSJed Brown     ierr = TSARKIMEXRegister(TSARKIMEXPRSSP2,2,3,&At[0][0],PETSC_NULL,PETSC_NULL,&A[0][0],PETSC_NULL,PETSC_NULL,PETSC_NULL,PETSC_NULL,0,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
2886cf0794eSJed Brown   }
289a3a57f36SJed Brown   {
290a3a57f36SJed Brown     const PetscReal
291a3a57f36SJed Brown       A[4][4] = {{0,0,0,0},
2924040e9f2SJed Brown                  {1767732205903./2027836641118.,0,0,0},
2934040e9f2SJed Brown                  {5535828885825./10492691773637.,788022342437./10882634858940.,0,0},
2944040e9f2SJed Brown                  {6485989280629./16251701735622.,-4246266847089./9704473918619.,10755448449292./10357097424841.,0}},
295a3a57f36SJed Brown       At[4][4] = {{0,0,0,0},
2964040e9f2SJed Brown                   {1767732205903./4055673282236.,1767732205903./4055673282236.,0,0},
2974040e9f2SJed Brown                   {2746238789719./10658868560708.,-640167445237./6845629431997.,1767732205903./4055673282236.,0},
2984040e9f2SJed Brown                   {1471266399579./7840856788654.,-4482444167858./7529755066697.,11266239266428./11593286722821.,1767732205903./4055673282236.}},
299cc46b9d1SJed Brown       bembedt[4] = {2756255671327./12835298489170.,-10771552573575./22201958757719.,9247589265047./10645013368117.,2193209047091./5459859503100.},
3004040e9f2SJed Brown       binterpt[4][2] = {{4655552711362./22874653954995., -215264564351./13552729205753.},
3014040e9f2SJed Brown                         {-18682724506714./9892148508045.,17870216137069./13817060693119.},
3024040e9f2SJed Brown                         {34259539580243./13192909600954.,-28141676662227./17317692491321.},
3034040e9f2SJed Brown                         {584795268549./6622622206610.,   2508943948391./7218656332882.}};
304108c343cSJed Brown     ierr = TSARKIMEXRegister(TSARKIMEX3,3,4,&At[0][0],PETSC_NULL,PETSC_NULL,&A[0][0],PETSC_NULL,PETSC_NULL,bembedt,bembedt,2,binterpt[0],PETSC_NULL);CHKERRQ(ierr);
305a3a57f36SJed Brown   }
306a3a57f36SJed Brown   {
307a3a57f36SJed Brown     const PetscReal
308e74514c0SSatish Balay       A[5][5] = {{0,0,0,0,0},
3096cf0794eSJed Brown                  {1./2,0,0,0,0},
3106cf0794eSJed Brown                  {11./18,1./18,0,0,0},
3116cf0794eSJed Brown                  {5./6,-5./6,.5,0,0},
3126cf0794eSJed Brown                  {1./4,7./4,3./4,-7./4,0}},
3136cf0794eSJed Brown       At[5][5] = {{0,0,0,0,0},
3146cf0794eSJed Brown                   {0,1./2,0,0,0},
3156cf0794eSJed Brown                   {0,1./6,1./2,0,0},
3166cf0794eSJed Brown                   {0,-1./2,1./2,1./2,0},
317108c343cSJed Brown                   {0,3./2,-3./2,1./2,1./2}},
318108c343cSJed Brown       *bembedt = PETSC_NULL;
319108c343cSJed Brown       ierr = TSARKIMEXRegister(TSARKIMEXARS443,3,5,&At[0][0],PETSC_NULL,PETSC_NULL,&A[0][0],PETSC_NULL,PETSC_NULL,bembedt,bembedt,0,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
3206cf0794eSJed Brown   }
3216cf0794eSJed Brown   {
3226cf0794eSJed Brown     const PetscReal
323e74514c0SSatish Balay       A[5][5] = {{0,0,0,0,0},
3246cf0794eSJed Brown                  {1,0,0,0,0},
3256cf0794eSJed Brown                  {4./9,2./9,0,0,0},
3266cf0794eSJed Brown                  {1./4,0,3./4,0,0},
3276cf0794eSJed Brown                  {1./4,0,3./5,0,0}},
328e74514c0SSatish Balay       At[5][5] = {{0,0,0,0,0},
3296cf0794eSJed Brown                   {.5,.5,0,0,0},
3306cf0794eSJed Brown                   {5./18,-1./9,.5,0,0},
3316cf0794eSJed Brown                   {.5,0,0,.5,0},
332108c343cSJed Brown                   {.25,0,.75,-.5,.5}},
333108c343cSJed Brown       *bembedt = PETSC_NULL;
334108c343cSJed Brown     ierr = TSARKIMEXRegister(TSARKIMEXBPR3,3,5,&At[0][0],PETSC_NULL,PETSC_NULL,&A[0][0],PETSC_NULL,PETSC_NULL,bembedt,bembedt,0,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
3356cf0794eSJed Brown   }
3366cf0794eSJed Brown   {
3376cf0794eSJed Brown     const PetscReal
338a3a57f36SJed Brown       A[6][6] = {{0,0,0,0,0,0},
339a3a57f36SJed Brown                  {1./2,0,0,0,0,0},
3404040e9f2SJed Brown                  {13861./62500.,6889./62500.,0,0,0,0},
3414040e9f2SJed Brown                  {-116923316275./2393684061468.,-2731218467317./15368042101831.,9408046702089./11113171139209.,0,0,0},
3424040e9f2SJed Brown                  {-451086348788./2902428689909.,-2682348792572./7519795681897.,12662868775082./11960479115383.,3355817975965./11060851509271.,0,0},
3434040e9f2SJed Brown                  {647845179188./3216320057751.,73281519250./8382639484533.,552539513391./3454668386233.,3354512671639./8306763924573.,4040./17871.,0}},
344a3a57f36SJed Brown       At[6][6] = {{0,0,0,0,0,0},
345a3a57f36SJed Brown                   {1./4,1./4,0,0,0,0},
3464040e9f2SJed Brown                   {8611./62500.,-1743./31250.,1./4,0,0,0},
3474040e9f2SJed Brown                   {5012029./34652500.,-654441./2922500.,174375./388108.,1./4,0,0},
3484040e9f2SJed Brown                   {15267082809./155376265600.,-71443401./120774400.,730878875./902184768.,2285395./8070912.,1./4,0},
3494040e9f2SJed Brown                   {82889./524892.,0,15625./83664.,69875./102672.,-2260./8211,1./4}},
350cc46b9d1SJed Brown       bembedt[6] = {4586570599./29645900160.,0,178811875./945068544.,814220225./1159782912.,-3700637./11593932.,61727./225920.},
3514040e9f2SJed Brown       binterpt[6][3] = {{6943876665148./7220017795957.,-54480133./30881146.,6818779379841./7100303317025.},
352cd652676SJed Brown                         {0,0,0},
3534040e9f2SJed Brown                         {7640104374378./9702883013639.,-11436875./14766696.,2173542590792./12501825683035.},
3544040e9f2SJed Brown                         {-20649996744609./7521556579894.,174696575./18121608.,-31592104683404./5083833661969.},
3554040e9f2SJed Brown                         {8854892464581./2390941311638.,-12120380./966161.,61146701046299./7138195549469.},
3564040e9f2SJed Brown                         {-11397109935349./6675773540249.,3843./706.,-17219254887155./4939391667607.}};
357108c343cSJed Brown     ierr = TSARKIMEXRegister(TSARKIMEX4,4,6,&At[0][0],PETSC_NULL,PETSC_NULL,&A[0][0],PETSC_NULL,PETSC_NULL,bembedt,bembedt,3,binterpt[0],PETSC_NULL);CHKERRQ(ierr);
358a3a57f36SJed Brown   }
359a3a57f36SJed Brown   {
360a3a57f36SJed Brown     const PetscReal
361a3a57f36SJed Brown       A[8][8] = {{0,0,0,0,0,0,0,0},
362a3a57f36SJed Brown                  {41./100,0,0,0,0,0,0,0},
3634040e9f2SJed Brown                  {367902744464./2072280473677.,677623207551./8224143866563.,0,0,0,0,0,0},
3644040e9f2SJed Brown                  {1268023523408./10340822734521.,0,1029933939417./13636558850479.,0,0,0,0,0},
3654040e9f2SJed Brown                  {14463281900351./6315353703477.,0,66114435211212./5879490589093.,-54053170152839./4284798021562.,0,0,0,0},
3664040e9f2SJed Brown                  {14090043504691./34967701212078.,0,15191511035443./11219624916014.,-18461159152457./12425892160975.,-281667163811./9011619295870.,0,0,0},
3674040e9f2SJed Brown                  {19230459214898./13134317526959.,0,21275331358303./2942455364971.,-38145345988419./4862620318723.,-1./8,-1./8,0,0},
3684040e9f2SJed Brown                  {-19977161125411./11928030595625.,0,-40795976796054./6384907823539.,177454434618887./12078138498510.,782672205425./8267701900261.,-69563011059811./9646580694205.,7356628210526./4942186776405.,0}},
369a3a57f36SJed Brown       At[8][8] = {{0,0,0,0,0,0,0,0},
3704040e9f2SJed Brown                   {41./200.,41./200.,0,0,0,0,0,0},
3714040e9f2SJed Brown                   {41./400.,-567603406766./11931857230679.,41./200.,0,0,0,0,0},
3724040e9f2SJed Brown                   {683785636431./9252920307686.,0,-110385047103./1367015193373.,41./200.,0,0,0,0},
3734040e9f2SJed Brown                   {3016520224154./10081342136671.,0,30586259806659./12414158314087.,-22760509404356./11113319521817.,41./200.,0,0,0},
3744040e9f2SJed Brown                   {218866479029./1489978393911.,0,638256894668./5436446318841.,-1179710474555./5321154724896.,-60928119172./8023461067671.,41./200.,0,0},
3754040e9f2SJed Brown                   {1020004230633./5715676835656.,0,25762820946817./25263940353407.,-2161375909145./9755907335909.,-211217309593./5846859502534.,-4269925059573./7827059040749.,41./200,0},
3764040e9f2SJed Brown                   {-872700587467./9133579230613.,0,0,22348218063261./9555858737531.,-1143369518992./8141816002931.,-39379526789629./19018526304540.,32727382324388./42900044865799.,41./200.}},
377cc46b9d1SJed Brown       bembedt[8] = {-975461918565./9796059967033.,0,0,78070527104295./32432590147079.,-548382580838./3424219808633.,-33438840321285./15594753105479.,3629800801594./4656183773603.,4035322873751./18575991585200.},
3784040e9f2SJed Brown       binterpt[8][3] = {{-17674230611817./10670229744614. ,  43486358583215./12773830924787. , -9257016797708./5021505065439.},
379cd652676SJed Brown                         {0                               ,  0                              , 0                            },
380cd652676SJed Brown                         {0                               ,  0                              , 0                            },
3814040e9f2SJed Brown                         {65168852399939./7868540260826.  ,  -91478233927265./11067650958493., 26096422576131./11239449250142.},
3824040e9f2SJed Brown                         {15494834004392./5936557850923.  ,  -79368583304911./10890268929626., 92396832856987./20362823103730.},
3834040e9f2SJed Brown                         {-99329723586156./26959484932159.,  -12239297817655./9152339842473. , 30029262896817./10175596800299.},
3844040e9f2SJed Brown                         {-19024464361622./5461577185407. ,  115839755401235./10719374521269., -26136350496073./3983972220547.},
3854040e9f2SJed Brown                         {-6511271360970./6095937251113.  ,  5843115559534./2180450260947.   , -5289405421727./3760307252460. }};
386108c343cSJed Brown     ierr = TSARKIMEXRegister(TSARKIMEX5,5,8,&At[0][0],PETSC_NULL,PETSC_NULL,&A[0][0],PETSC_NULL,PETSC_NULL,bembedt,bembedt,3,binterpt[0],PETSC_NULL);CHKERRQ(ierr);
387a3a57f36SJed Brown   }
388a3a57f36SJed Brown 
3898a381b04SJed Brown   PetscFunctionReturn(0);
3908a381b04SJed Brown }
3918a381b04SJed Brown 
3928a381b04SJed Brown #undef __FUNCT__
3938a381b04SJed Brown #define __FUNCT__ "TSARKIMEXRegisterDestroy"
3948a381b04SJed Brown /*@C
3958a381b04SJed Brown    TSARKIMEXRegisterDestroy - Frees the list of schemes that were registered by TSARKIMEXRegister().
3968a381b04SJed Brown 
3978a381b04SJed Brown    Not Collective
3988a381b04SJed Brown 
3998a381b04SJed Brown    Level: advanced
4008a381b04SJed Brown 
4018a381b04SJed Brown .keywords: TSARKIMEX, register, destroy
4028a381b04SJed Brown .seealso: TSARKIMEXRegister(), TSARKIMEXRegisterAll(), TSARKIMEXRegisterDynamic()
4038a381b04SJed Brown @*/
4048a381b04SJed Brown PetscErrorCode TSARKIMEXRegisterDestroy(void)
4058a381b04SJed Brown {
4068a381b04SJed Brown   PetscErrorCode ierr;
4078a381b04SJed Brown   ARKTableauLink link;
4088a381b04SJed Brown 
4098a381b04SJed Brown   PetscFunctionBegin;
4108a381b04SJed Brown   while ((link = ARKTableauList)) {
4118a381b04SJed Brown     ARKTableau t = &link->tab;
4128a381b04SJed Brown     ARKTableauList = link->next;
4138a381b04SJed Brown     ierr = PetscFree6(t->At,t->bt,t->ct,t->A,t->b,t->c);CHKERRQ(ierr);
414108c343cSJed Brown     ierr = PetscFree2(t->bembedt,t->bembed);CHKERRQ(ierr);
415cd652676SJed Brown     ierr = PetscFree2(t->binterpt,t->binterp);CHKERRQ(ierr);
4168a381b04SJed Brown     ierr = PetscFree(t->name);CHKERRQ(ierr);
4178a381b04SJed Brown     ierr = PetscFree(link);CHKERRQ(ierr);
4188a381b04SJed Brown   }
4198a381b04SJed Brown   TSARKIMEXRegisterAllCalled = PETSC_FALSE;
4208a381b04SJed Brown   PetscFunctionReturn(0);
4218a381b04SJed Brown }
4228a381b04SJed Brown 
4238a381b04SJed Brown #undef __FUNCT__
4248a381b04SJed Brown #define __FUNCT__ "TSARKIMEXInitializePackage"
4258a381b04SJed Brown /*@C
4268a381b04SJed Brown   TSARKIMEXInitializePackage - This function initializes everything in the TSARKIMEX package. It is called
4278a381b04SJed Brown   from PetscDLLibraryRegister() when using dynamic libraries, and on the first call to TSCreate_ARKIMEX()
4288a381b04SJed Brown   when using static libraries.
4298a381b04SJed Brown 
4308a381b04SJed Brown   Input Parameter:
4318a381b04SJed Brown   path - The dynamic library path, or PETSC_NULL
4328a381b04SJed Brown 
4338a381b04SJed Brown   Level: developer
4348a381b04SJed Brown 
4358a381b04SJed Brown .keywords: TS, TSARKIMEX, initialize, package
4368a381b04SJed Brown .seealso: PetscInitialize()
4378a381b04SJed Brown @*/
4388a381b04SJed Brown PetscErrorCode TSARKIMEXInitializePackage(const char path[])
4398a381b04SJed Brown {
4408a381b04SJed Brown   PetscErrorCode ierr;
4418a381b04SJed Brown 
4428a381b04SJed Brown   PetscFunctionBegin;
4438a381b04SJed Brown   if (TSARKIMEXPackageInitialized) PetscFunctionReturn(0);
4448a381b04SJed Brown   TSARKIMEXPackageInitialized = PETSC_TRUE;
4458a381b04SJed Brown   ierr = TSARKIMEXRegisterAll();CHKERRQ(ierr);
4468a381b04SJed Brown   ierr = PetscRegisterFinalize(TSARKIMEXFinalizePackage);CHKERRQ(ierr);
4478a381b04SJed Brown   PetscFunctionReturn(0);
4488a381b04SJed Brown }
4498a381b04SJed Brown 
4508a381b04SJed Brown #undef __FUNCT__
4518a381b04SJed Brown #define __FUNCT__ "TSARKIMEXFinalizePackage"
4528a381b04SJed Brown /*@C
4538a381b04SJed Brown   TSARKIMEXFinalizePackage - This function destroys everything in the TSARKIMEX package. It is
4548a381b04SJed Brown   called from PetscFinalize().
4558a381b04SJed Brown 
4568a381b04SJed Brown   Level: developer
4578a381b04SJed Brown 
4588a381b04SJed Brown .keywords: Petsc, destroy, package
4598a381b04SJed Brown .seealso: PetscFinalize()
4608a381b04SJed Brown @*/
4618a381b04SJed Brown PetscErrorCode TSARKIMEXFinalizePackage(void)
4628a381b04SJed Brown {
4638a381b04SJed Brown   PetscErrorCode ierr;
4648a381b04SJed Brown 
4658a381b04SJed Brown   PetscFunctionBegin;
4668a381b04SJed Brown   TSARKIMEXPackageInitialized = PETSC_FALSE;
4678a381b04SJed Brown   ierr = TSARKIMEXRegisterDestroy();CHKERRQ(ierr);
4688a381b04SJed Brown   PetscFunctionReturn(0);
4698a381b04SJed Brown }
4708a381b04SJed Brown 
4718a381b04SJed Brown #undef __FUNCT__
4728a381b04SJed Brown #define __FUNCT__ "TSARKIMEXRegister"
473cd652676SJed Brown /*@C
474cd652676SJed Brown    TSARKIMEXRegister - register an ARK IMEX scheme by providing the entries in the Butcher tableau and optionally embedded approximations and interpolation
475cd652676SJed Brown 
476cd652676SJed Brown    Not Collective, but the same schemes should be registered on all processes on which they will be used
477cd652676SJed Brown 
478cd652676SJed Brown    Input Parameters:
479cd652676SJed Brown +  name - identifier for method
480cd652676SJed Brown .  order - approximation order of method
481cd652676SJed Brown .  s - number of stages, this is the dimension of the matrices below
482cd652676SJed Brown .  At - Butcher table of stage coefficients for stiff part (dimension s*s, row-major)
483cd652676SJed Brown .  bt - Butcher table for completing the stiff part of the step (dimension s; PETSC_NULL to use the last row of At)
484cd652676SJed Brown .  ct - Abscissa of each stiff stage (dimension s, PETSC_NULL to use row sums of At)
485cd652676SJed Brown .  A - Non-stiff stage coefficients (dimension s*s, row-major)
486cd652676SJed Brown .  b - Non-stiff step completion table (dimension s; PETSC_NULL to use last row of At)
487cd652676SJed Brown .  c - Non-stiff abscissa (dimension s; PETSC_NULL to use row sums of A)
488108c343cSJed Brown .  bembedt - Stiff part of completion table for embedded method (dimension s; PETSC_NULL if not available)
489108c343cSJed Brown .  bembed - Non-stiff part of completion table for embedded method (dimension s; PETSC_NULL to use bembedt if provided)
490cd652676SJed Brown .  pinterp - Order of the interpolation scheme, equal to the number of columns of binterpt and binterp
491cd652676SJed Brown .  binterpt - Coefficients of the interpolation formula for the stiff part (dimension s*pinterp)
492cd652676SJed Brown -  binterp - Coefficients of the interpolation formula for the non-stiff part (dimension s*pinterp; PETSC_NULL to reuse binterpt)
493cd652676SJed Brown 
494cd652676SJed Brown    Notes:
495cd652676SJed Brown    Several ARK IMEX methods are provided, this function is only needed to create new methods.
496cd652676SJed Brown 
497cd652676SJed Brown    Level: advanced
498cd652676SJed Brown 
499cd652676SJed Brown .keywords: TS, register
500cd652676SJed Brown 
501cd652676SJed Brown .seealso: TSARKIMEX
502cd652676SJed Brown @*/
50319fd82e9SBarry Smith PetscErrorCode TSARKIMEXRegister(TSARKIMEXType name,PetscInt order,PetscInt s,
5048a381b04SJed Brown                                  const PetscReal At[],const PetscReal bt[],const PetscReal ct[],
505cd652676SJed Brown                                  const PetscReal A[],const PetscReal b[],const PetscReal c[],
506108c343cSJed Brown                                  const PetscReal bembedt[],const PetscReal bembed[],
507cd652676SJed Brown                                  PetscInt pinterp,const PetscReal binterpt[],const PetscReal binterp[])
5088a381b04SJed Brown {
5098a381b04SJed Brown   PetscErrorCode ierr;
5108a381b04SJed Brown   ARKTableauLink link;
5118a381b04SJed Brown   ARKTableau     t;
5128a381b04SJed Brown   PetscInt       i,j;
5138a381b04SJed Brown 
5148a381b04SJed Brown   PetscFunctionBegin;
5158a381b04SJed Brown   ierr = PetscMalloc(sizeof(*link),&link);CHKERRQ(ierr);
516cd652676SJed Brown   ierr = PetscMemzero(link,sizeof(*link));CHKERRQ(ierr);
5178a381b04SJed Brown   t = &link->tab;
5188a381b04SJed Brown   ierr = PetscStrallocpy(name,&t->name);CHKERRQ(ierr);
5198a381b04SJed Brown   t->order = order;
5208a381b04SJed Brown   t->s = s;
5218a381b04SJed 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);
5228a381b04SJed Brown   ierr = PetscMemcpy(t->At,At,s*s*sizeof(At[0]));CHKERRQ(ierr);
5238a381b04SJed Brown   ierr = PetscMemcpy(t->A,A,s*s*sizeof(A[0]));CHKERRQ(ierr);
5248a381b04SJed Brown   if (bt) {ierr = PetscMemcpy(t->bt,bt,s*sizeof(bt[0]));CHKERRQ(ierr);}
5258a381b04SJed Brown   else for (i=0; i<s; i++) t->bt[i] = At[(s-1)*s+i];
5268a381b04SJed Brown   if (b) {ierr = PetscMemcpy(t->b,b,s*sizeof(b[0]));CHKERRQ(ierr);}
5278a381b04SJed Brown   else for (i=0; i<s; i++) t->b[i] = At[(s-1)*s+i];
5288a381b04SJed Brown   if (ct) {ierr = PetscMemcpy(t->ct,ct,s*sizeof(ct[0]));CHKERRQ(ierr);}
5298a381b04SJed 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];
5308a381b04SJed Brown   if (c) {ierr = PetscMemcpy(t->c,c,s*sizeof(c[0]));CHKERRQ(ierr);}
5318a381b04SJed 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];
532108c343cSJed Brown   if (bembedt) {
533108c343cSJed Brown     ierr = PetscMalloc2(s,PetscReal,&t->bembedt,s,PetscReal,&t->bembed);CHKERRQ(ierr);
534108c343cSJed Brown     ierr = PetscMemcpy(t->bembedt,bembedt,s*sizeof(bembedt[0]));CHKERRQ(ierr);
535108c343cSJed Brown     ierr = PetscMemcpy(t->bembed,bembed?bembed:bembedt,s*sizeof(bembed[0]));CHKERRQ(ierr);
536108c343cSJed Brown   }
537108c343cSJed Brown 
5384f385281SJed Brown   t->pinterp = pinterp;
539cd652676SJed Brown   ierr = PetscMalloc2(s*pinterp,PetscReal,&t->binterpt,s*pinterp,PetscReal,&t->binterp);CHKERRQ(ierr);
540cd652676SJed Brown   ierr = PetscMemcpy(t->binterpt,binterpt,s*pinterp*sizeof(binterpt[0]));CHKERRQ(ierr);
541cd652676SJed Brown   ierr = PetscMemcpy(t->binterp,binterp?binterp:binterpt,s*pinterp*sizeof(binterpt[0]));CHKERRQ(ierr);
5428a381b04SJed Brown   link->next = ARKTableauList;
5438a381b04SJed Brown   ARKTableauList = link;
5448a381b04SJed Brown   PetscFunctionReturn(0);
5458a381b04SJed Brown }
5468a381b04SJed Brown 
5478a381b04SJed Brown #undef __FUNCT__
548108c343cSJed Brown #define __FUNCT__ "TSEvaluateStep_ARKIMEX"
549108c343cSJed Brown /*
550108c343cSJed Brown  The step completion formula is
551108c343cSJed Brown 
552108c343cSJed Brown  x1 = x0 - h bt^T YdotI + h b^T YdotRHS
553108c343cSJed Brown 
554108c343cSJed Brown  This function can be called before or after ts->vec_sol has been updated.
555108c343cSJed Brown  Suppose we have a completion formula (bt,b) and an embedded formula (bet,be) of different order.
556108c343cSJed Brown  We can write
557108c343cSJed Brown 
558108c343cSJed Brown  x1e = x0 - h bet^T YdotI + h be^T YdotRHS
559108c343cSJed Brown      = x1 + h bt^T YdotI - h b^T YdotRHS - h bet^T YdotI + h be^T YdotRHS
560108c343cSJed Brown      = x1 - h (bet - bt)^T YdotI + h (be - b)^T YdotRHS
561108c343cSJed Brown 
562108c343cSJed Brown  so we can evaluate the method with different order even after the step has been optimistically completed.
563108c343cSJed Brown */
564108c343cSJed Brown static PetscErrorCode TSEvaluateStep_ARKIMEX(TS ts,PetscInt order,Vec X,PetscBool *done)
565108c343cSJed Brown {
566108c343cSJed Brown   TS_ARKIMEX     *ark = (TS_ARKIMEX*)ts->data;
567108c343cSJed Brown   ARKTableau     tab  = ark->tableau;
568108c343cSJed Brown   PetscScalar    *w = ark->work;
569108c343cSJed Brown   PetscReal      h;
570108c343cSJed Brown   PetscInt       s = tab->s,j;
571108c343cSJed Brown   PetscErrorCode ierr;
572108c343cSJed Brown 
573108c343cSJed Brown   PetscFunctionBegin;
574108c343cSJed Brown   switch (ark->status) {
575108c343cSJed Brown   case TS_STEP_INCOMPLETE:
576108c343cSJed Brown   case TS_STEP_PENDING:
577108c343cSJed Brown     h = ts->time_step; break;
578108c343cSJed Brown   case TS_STEP_COMPLETE:
579108c343cSJed Brown     h = ts->time_step_prev; break;
580b9ce6d65SJed Brown   default: SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_PLIB,"Invalid TSStepStatus");
581108c343cSJed Brown   }
582108c343cSJed Brown   if (order == tab->order) {
583108c343cSJed Brown     if (ark->status == TS_STEP_INCOMPLETE) { /* Use the standard completion formula (bt,b) */
584108c343cSJed Brown       ierr = VecCopy(ts->vec_sol,X);CHKERRQ(ierr);
585108c343cSJed Brown       for (j=0; j<s; j++) w[j] = -h*tab->bt[j];
586108c343cSJed Brown       ierr = VecMAXPY(X,s,w,ark->YdotI);CHKERRQ(ierr);
587108c343cSJed Brown       for (j=0; j<s; j++) w[j] = h*tab->b[j];
588108c343cSJed Brown       ierr = VecMAXPY(X,s,w,ark->YdotRHS);CHKERRQ(ierr);
589108c343cSJed Brown     } else {ierr = VecCopy(ts->vec_sol,X);CHKERRQ(ierr);}
590108c343cSJed Brown     if (done) *done = PETSC_TRUE;
591108c343cSJed Brown     PetscFunctionReturn(0);
592108c343cSJed Brown   } else if (order == tab->order-1) {
593108c343cSJed Brown     if (!tab->bembedt) goto unavailable;
594108c343cSJed Brown     if (ark->status == TS_STEP_INCOMPLETE) { /* Complete with the embedded method (bet,be) */
595108c343cSJed Brown       ierr = VecCopy(ts->vec_sol,X);CHKERRQ(ierr);
596108c343cSJed Brown       for (j=0; j<s; j++) w[j] = -h*tab->bembedt[j];
597108c343cSJed Brown       ierr = VecMAXPY(X,s,w,ark->YdotI);CHKERRQ(ierr);
598108c343cSJed Brown       for (j=0; j<s; j++) w[j] = h*tab->bembed[j];
599108c343cSJed Brown       ierr = VecMAXPY(X,s,w,ark->YdotRHS);CHKERRQ(ierr);
600108c343cSJed Brown     } else {                    /* Rollback and re-complete using (bet-be,be-b) */
601108c343cSJed Brown       ierr = VecCopy(ts->vec_sol,X);CHKERRQ(ierr);
602108c343cSJed Brown       for (j=0; j<s; j++) w[j] = -h*(tab->bembedt[j] - tab->bt[j]);
603108c343cSJed Brown       ierr = VecMAXPY(X,tab->s,w,ark->YdotI);CHKERRQ(ierr);
604108c343cSJed Brown       for (j=0; j<s; j++) w[j] = h*(tab->bembed[j] - tab->b[j]);
605108c343cSJed Brown       ierr = VecMAXPY(X,s,w,ark->YdotRHS);CHKERRQ(ierr);
606108c343cSJed Brown     }
607108c343cSJed Brown     if (done) *done = PETSC_TRUE;
608108c343cSJed Brown     PetscFunctionReturn(0);
609108c343cSJed Brown   }
610108c343cSJed Brown   unavailable:
611108c343cSJed Brown   if (done) *done = PETSC_FALSE;
612108c343cSJed Brown   else SETERRQ3(((PetscObject)ts)->comm,PETSC_ERR_SUP,"ARKIMEX '%s' of order %D cannot evaluate step at order %D",tab->name,tab->order,order);
613108c343cSJed Brown   PetscFunctionReturn(0);
614108c343cSJed Brown }
615108c343cSJed Brown 
616108c343cSJed Brown #undef __FUNCT__
6178a381b04SJed Brown #define __FUNCT__ "TSStep_ARKIMEX"
6188a381b04SJed Brown static PetscErrorCode TSStep_ARKIMEX(TS ts)
6198a381b04SJed Brown {
6208a381b04SJed Brown   TS_ARKIMEX          *ark = (TS_ARKIMEX*)ts->data;
6218a381b04SJed Brown   ARKTableau          tab  = ark->tableau;
6228a381b04SJed Brown   const PetscInt      s    = tab->s;
6238a381b04SJed Brown   const PetscReal     *At  = tab->At,*A = tab->A,*bt = tab->bt,*b = tab->b,*ct = tab->ct,*c = tab->c;
624406d0ec2SJed Brown   PetscScalar         *w   = ark->work;
6258a381b04SJed Brown   Vec                 *Y   = ark->Y,*YdotI = ark->YdotI,*YdotRHS = ark->YdotRHS,Ydot = ark->Ydot,W = ark->Work,Z = ark->Z;
626108c343cSJed Brown   TSAdapt             adapt;
6278a381b04SJed Brown   SNES                snes;
628108c343cSJed Brown   PetscInt            i,j,its,lits,reject,next_scheme;
629cdbf8f93SLisandro Dalcin   PetscReal           next_time_step;
630108c343cSJed Brown   PetscReal           t;
631108c343cSJed Brown   PetscBool           accept;
6328a381b04SJed Brown   PetscErrorCode      ierr;
6338a381b04SJed Brown 
6348a381b04SJed Brown   PetscFunctionBegin;
6358a381b04SJed Brown   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
636cdbf8f93SLisandro Dalcin   next_time_step = ts->time_step;
6378a381b04SJed Brown   t = ts->ptime;
638108c343cSJed Brown   accept = PETSC_TRUE;
639108c343cSJed Brown   ark->status = TS_STEP_INCOMPLETE;
6408a381b04SJed Brown 
64197335746SJed Brown   for (reject=0; reject<ts->max_reject && !ts->reason; reject++,ts->reject++) {
642108c343cSJed Brown     PetscReal h = ts->time_step;
643b8123daeSJed Brown     ierr = TSPreStep(ts);CHKERRQ(ierr);
6448a381b04SJed Brown     for (i=0; i<s; i++) {
6458a381b04SJed Brown       if (At[i*s+i] == 0) {           /* This stage is explicit */
6468a381b04SJed Brown         ierr = VecCopy(ts->vec_sol,Y[i]);CHKERRQ(ierr);
6478a381b04SJed Brown         for (j=0; j<i; j++) w[j] = -h*At[i*s+j];
6488a381b04SJed Brown         ierr = VecMAXPY(Y[i],i,w,YdotI);CHKERRQ(ierr);
6498a381b04SJed Brown         for (j=0; j<i; j++) w[j] = h*A[i*s+j];
6508a381b04SJed Brown         ierr = VecMAXPY(Y[i],i,w,YdotRHS);CHKERRQ(ierr);
6518a381b04SJed Brown       } else {
6528a381b04SJed Brown         ark->stage_time = t + h*ct[i];
653b296d7d5SJed Brown         ark->scoeff = 1./At[i*s+i];
654b8123daeSJed Brown         ierr = TSPreStage(ts,ark->stage_time);CHKERRQ(ierr);
6558a381b04SJed Brown         /* Affine part */
6568a381b04SJed Brown         ierr = VecZeroEntries(W);CHKERRQ(ierr);
6578a381b04SJed Brown         for (j=0; j<i; j++) w[j] = h*A[i*s+j];
6588a381b04SJed Brown         ierr = VecMAXPY(W,i,w,YdotRHS);CHKERRQ(ierr);
659b296d7d5SJed Brown         ierr = VecScale(W, ark->scoeff/h);CHKERRQ(ierr);
660f16577ceSEmil Constantinescu 
6618a381b04SJed Brown         /* Ydot = shift*(Y-Z) */
6628a381b04SJed Brown         ierr = VecCopy(ts->vec_sol,Z);CHKERRQ(ierr);
6634f385281SJed Brown         for (j=0; j<i; j++) w[j] = -h*At[i*s+j];
6644f385281SJed Brown         ierr = VecMAXPY(Z,i,w,YdotI);CHKERRQ(ierr);
665f16577ceSEmil Constantinescu 
6668a381b04SJed Brown         /* Initial guess taken from last stage */
6678a381b04SJed Brown         ierr = VecCopy(i>0?Y[i-1]:ts->vec_sol,Y[i]);CHKERRQ(ierr);
6688a381b04SJed Brown         ierr = SNESSolve(snes,W,Y[i]);CHKERRQ(ierr);
6698a381b04SJed Brown         ierr = SNESGetIterationNumber(snes,&its);CHKERRQ(ierr);
6708a381b04SJed Brown         ierr = SNESGetLinearSolveIterations(snes,&lits);CHKERRQ(ierr);
6715ef26d82SJed Brown         ts->snes_its += its; ts->ksp_its += lits;
672ad6bc421SBarry Smith         ierr = TSGetTSAdapt(ts,&adapt);CHKERRQ(ierr);
67397335746SJed Brown         ierr = TSAdaptCheckStage(adapt,ts,&accept);CHKERRQ(ierr);
67497335746SJed Brown         if (!accept) goto reject_step;
6758a381b04SJed Brown       }
6768a381b04SJed Brown       ierr = VecZeroEntries(Ydot);CHKERRQ(ierr);
6774cc180ffSJed Brown       ierr = TSComputeIFunction(ts,t+h*ct[i],Y[i],Ydot,YdotI[i],ark->imex);CHKERRQ(ierr);
6784cc180ffSJed Brown       if (ark->imex) {
6798a381b04SJed Brown         ierr = TSComputeRHSFunction(ts,t+h*c[i],Y[i],YdotRHS[i]);CHKERRQ(ierr);
6804cc180ffSJed Brown       } else {
6814cc180ffSJed Brown         ierr = VecZeroEntries(YdotRHS[i]);CHKERRQ(ierr);
6824cc180ffSJed Brown       }
6838a381b04SJed Brown     }
684108c343cSJed Brown     ierr = TSEvaluateStep(ts,tab->order,ts->vec_sol,PETSC_NULL);CHKERRQ(ierr);
685108c343cSJed Brown     ark->status = TS_STEP_PENDING;
6868a381b04SJed Brown 
687108c343cSJed Brown     /* Register only the current method as a candidate because we're not supporting multiple candidates yet. */
688ad6bc421SBarry Smith     ierr = TSGetTSAdapt(ts,&adapt);CHKERRQ(ierr);
689108c343cSJed Brown     ierr = TSAdaptCandidatesClear(adapt);CHKERRQ(ierr);
690108c343cSJed Brown     ierr = TSAdaptCandidateAdd(adapt,tab->name,tab->order,1,tab->ccfl,1.*tab->s,PETSC_TRUE);CHKERRQ(ierr);
691108c343cSJed Brown     ierr = TSAdaptChoose(adapt,ts,ts->time_step,&next_scheme,&next_time_step,&accept);CHKERRQ(ierr);
692108c343cSJed Brown     if (accept) {
693108c343cSJed Brown       /* ignore next_scheme for now */
6948a381b04SJed Brown       ts->ptime += ts->time_step;
695cdbf8f93SLisandro Dalcin       ts->time_step = next_time_step;
6968a381b04SJed Brown       ts->steps++;
697108c343cSJed Brown       ark->status = TS_STEP_COMPLETE;
698108c343cSJed Brown       break;
699108c343cSJed Brown     } else {                    /* Roll back the current step */
700108c343cSJed Brown       for (j=0; j<s; j++) w[j] = h*bt[j];
701108c343cSJed Brown       ierr = VecMAXPY(ts->vec_sol,s,w,ark->YdotI);CHKERRQ(ierr);
702108c343cSJed Brown       for (j=0; j<s; j++) w[j] = -h*b[j];
703108c343cSJed Brown       ierr = VecMAXPY(ts->vec_sol,s,w,ark->YdotRHS);CHKERRQ(ierr);
704108c343cSJed Brown       ts->time_step = next_time_step;
705108c343cSJed Brown       ark->status = TS_STEP_INCOMPLETE;
706108c343cSJed Brown     }
707476b6736SJed Brown     reject_step: continue;
708108c343cSJed Brown   }
709b2ce242eSJed Brown   if (ark->status != TS_STEP_COMPLETE && !ts->reason) ts->reason = TS_DIVERGED_STEP_REJECTED;
7108a381b04SJed Brown   PetscFunctionReturn(0);
7118a381b04SJed Brown }
7128a381b04SJed Brown 
713cd652676SJed Brown #undef __FUNCT__
714cd652676SJed Brown #define __FUNCT__ "TSInterpolate_ARKIMEX"
715cd652676SJed Brown static PetscErrorCode TSInterpolate_ARKIMEX(TS ts,PetscReal itime,Vec X)
716cd652676SJed Brown {
717cd652676SJed Brown   TS_ARKIMEX      *ark = (TS_ARKIMEX*)ts->data;
7184f385281SJed Brown   PetscInt        s = ark->tableau->s,pinterp = ark->tableau->pinterp,i,j;
719108c343cSJed Brown   PetscReal       h;
720108c343cSJed Brown   PetscReal       tt,t;
721cd652676SJed Brown   PetscScalar     *bt,*b;
722cd652676SJed Brown   const PetscReal *Bt = ark->tableau->binterpt,*B = ark->tableau->binterp;
723cd652676SJed Brown   PetscErrorCode  ierr;
724cd652676SJed Brown 
725cd652676SJed Brown   PetscFunctionBegin;
726cd652676SJed Brown   if (!Bt || !B) SETERRQ1(((PetscObject)ts)->comm,PETSC_ERR_SUP,"TSARKIMEX %s does not have an interpolation formula",ark->tableau->name);
727108c343cSJed Brown   switch (ark->status) {
728108c343cSJed Brown   case TS_STEP_INCOMPLETE:
729108c343cSJed Brown   case TS_STEP_PENDING:
730108c343cSJed Brown     h = ts->time_step;
731108c343cSJed Brown     t = (itime - ts->ptime)/h;
732108c343cSJed Brown     break;
733108c343cSJed Brown   case TS_STEP_COMPLETE:
734108c343cSJed Brown     h = ts->time_step_prev;
735108c343cSJed Brown     t = (itime - ts->ptime)/h + 1; /* In the interval [0,1] */
736108c343cSJed Brown     break;
737b9ce6d65SJed Brown   default: SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_PLIB,"Invalid TSStepStatus");
738108c343cSJed Brown   }
739cd652676SJed Brown   ierr = PetscMalloc2(s,PetscScalar,&bt,s,PetscScalar,&b);CHKERRQ(ierr);
740cd652676SJed Brown   for (i=0; i<s; i++) bt[i] = b[i] = 0;
7414f385281SJed Brown   for (j=0,tt=t; j<pinterp; j++,tt*=t) {
742cd652676SJed Brown     for (i=0; i<s; i++) {
743108c343cSJed Brown       bt[i] += h * Bt[i*pinterp+j] * tt * -1.0;
744108c343cSJed Brown       b[i]  += h * B[i*pinterp+j] * tt;
745cd652676SJed Brown     }
746cd652676SJed Brown   }
747cd652676SJed 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");
748cd652676SJed Brown   ierr = VecCopy(ark->Y[0],X);CHKERRQ(ierr);
749cd652676SJed Brown   ierr = VecMAXPY(X,s,bt,ark->YdotI);CHKERRQ(ierr);
750cd652676SJed Brown   ierr = VecMAXPY(X,s,b,ark->YdotRHS);CHKERRQ(ierr);
751cd652676SJed Brown   ierr = PetscFree2(bt,b);CHKERRQ(ierr);
752cd652676SJed Brown   PetscFunctionReturn(0);
753cd652676SJed Brown }
754cd652676SJed Brown 
7558a381b04SJed Brown /*------------------------------------------------------------*/
7568a381b04SJed Brown #undef __FUNCT__
7578a381b04SJed Brown #define __FUNCT__ "TSReset_ARKIMEX"
7588a381b04SJed Brown static PetscErrorCode TSReset_ARKIMEX(TS ts)
7598a381b04SJed Brown {
7608a381b04SJed Brown   TS_ARKIMEX      *ark = (TS_ARKIMEX*)ts->data;
7618a381b04SJed Brown   PetscInt        s;
7628a381b04SJed Brown   PetscErrorCode  ierr;
7638a381b04SJed Brown 
7648a381b04SJed Brown   PetscFunctionBegin;
7658a381b04SJed Brown   if (!ark->tableau) PetscFunctionReturn(0);
7668a381b04SJed Brown   s = ark->tableau->s;
7678a381b04SJed Brown   ierr = VecDestroyVecs(s,&ark->Y);CHKERRQ(ierr);
7688a381b04SJed Brown   ierr = VecDestroyVecs(s,&ark->YdotI);CHKERRQ(ierr);
7698a381b04SJed Brown   ierr = VecDestroyVecs(s,&ark->YdotRHS);CHKERRQ(ierr);
7708a381b04SJed Brown   ierr = VecDestroy(&ark->Ydot);CHKERRQ(ierr);
7718a381b04SJed Brown   ierr = VecDestroy(&ark->Work);CHKERRQ(ierr);
7728a381b04SJed Brown   ierr = VecDestroy(&ark->Z);CHKERRQ(ierr);
7738a381b04SJed Brown   ierr = PetscFree(ark->work);CHKERRQ(ierr);
7748a381b04SJed Brown   PetscFunctionReturn(0);
7758a381b04SJed Brown }
7768a381b04SJed Brown 
7778a381b04SJed Brown #undef __FUNCT__
7788a381b04SJed Brown #define __FUNCT__ "TSDestroy_ARKIMEX"
7798a381b04SJed Brown static PetscErrorCode TSDestroy_ARKIMEX(TS ts)
7808a381b04SJed Brown {
7818a381b04SJed Brown   PetscErrorCode  ierr;
7828a381b04SJed Brown 
7838a381b04SJed Brown   PetscFunctionBegin;
7848a381b04SJed Brown   ierr = TSReset_ARKIMEX(ts);CHKERRQ(ierr);
7858a381b04SJed Brown   ierr = PetscFree(ts->data);CHKERRQ(ierr);
7868a381b04SJed Brown   ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSARKIMEXGetType_C","",PETSC_NULL);CHKERRQ(ierr);
7878a381b04SJed Brown   ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSARKIMEXSetType_C","",PETSC_NULL);CHKERRQ(ierr);
788995b3938SJed Brown   ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSARKIMEXSetFullyImplicit_C","",PETSC_NULL);CHKERRQ(ierr);
7898a381b04SJed Brown   PetscFunctionReturn(0);
7908a381b04SJed Brown }
7918a381b04SJed Brown 
792d5e6173cSPeter Brune 
793d5e6173cSPeter Brune #undef __FUNCT__
794d5e6173cSPeter Brune #define __FUNCT__ "TSARKIMEXGetVecs"
795d5e6173cSPeter Brune static PetscErrorCode TSARKIMEXGetVecs(TS ts,DM dm,Vec *Z,Vec *Ydot)
796d5e6173cSPeter Brune {
797d5e6173cSPeter Brune   TS_ARKIMEX     *ax = (TS_ARKIMEX*)ts->data;
798d5e6173cSPeter Brune   PetscErrorCode ierr;
799d5e6173cSPeter Brune 
800d5e6173cSPeter Brune   PetscFunctionBegin;
801d5e6173cSPeter Brune   if (Z) {
802d5e6173cSPeter Brune     if (dm && dm != ts->dm) {
803d5e6173cSPeter Brune       ierr = DMGetNamedGlobalVector(dm,"TSARKIMEX_Z",Z);CHKERRQ(ierr);
804d5e6173cSPeter Brune     } else *Z = ax->Z;
805d5e6173cSPeter Brune   }
806d5e6173cSPeter Brune   if (Ydot) {
807d5e6173cSPeter Brune     if (dm && dm != ts->dm) {
808d5e6173cSPeter Brune       ierr = DMGetNamedGlobalVector(dm,"TSARKIMEX_Ydot",Ydot);CHKERRQ(ierr);
809d5e6173cSPeter Brune     } else *Ydot = ax->Ydot;
810d5e6173cSPeter Brune   }
811d5e6173cSPeter Brune   PetscFunctionReturn(0);
812d5e6173cSPeter Brune }
813d5e6173cSPeter Brune 
814d5e6173cSPeter Brune 
815d5e6173cSPeter Brune #undef __FUNCT__
816d5e6173cSPeter Brune #define __FUNCT__ "TSARKIMEXRestoreVecs"
817d5e6173cSPeter Brune static PetscErrorCode TSARKIMEXRestoreVecs(TS ts,DM dm,Vec *Z,Vec *Ydot)
818d5e6173cSPeter Brune {
819d5e6173cSPeter Brune   PetscErrorCode ierr;
820d5e6173cSPeter Brune 
821d5e6173cSPeter Brune   PetscFunctionBegin;
822d5e6173cSPeter Brune   if (Z) {
823d5e6173cSPeter Brune     if (dm && dm != ts->dm) {
824d5e6173cSPeter Brune       ierr = DMRestoreNamedGlobalVector(dm,"TSARKIMEX_Z",Z);CHKERRQ(ierr);
825d5e6173cSPeter Brune     }
826d5e6173cSPeter Brune   }
827d5e6173cSPeter Brune   if (Ydot) {
828d5e6173cSPeter Brune     if (dm && dm != ts->dm) {
829d5e6173cSPeter Brune       ierr = DMRestoreNamedGlobalVector(dm,"TSARKIMEX_Ydot",Ydot);CHKERRQ(ierr);
830d5e6173cSPeter Brune     }
831d5e6173cSPeter Brune   }
832d5e6173cSPeter Brune   PetscFunctionReturn(0);
833d5e6173cSPeter Brune }
834d5e6173cSPeter Brune 
8358a381b04SJed Brown /*
8368a381b04SJed Brown   This defines the nonlinear equation that is to be solved with SNES
8378a381b04SJed Brown   G(U) = F[t0+Theta*dt, U, (U-U0)*shift] = 0
8388a381b04SJed Brown */
8398a381b04SJed Brown #undef __FUNCT__
8408a381b04SJed Brown #define __FUNCT__ "SNESTSFormFunction_ARKIMEX"
8418a381b04SJed Brown static PetscErrorCode SNESTSFormFunction_ARKIMEX(SNES snes,Vec X,Vec F,TS ts)
8428a381b04SJed Brown {
8438a381b04SJed Brown   TS_ARKIMEX     *ark = (TS_ARKIMEX*)ts->data;
844d5e6173cSPeter Brune   DM             dm,dmsave;
845d5e6173cSPeter Brune   Vec            Z,Ydot;
846b296d7d5SJed Brown   PetscReal      shift = ark->scoeff / ts->time_step;
8478a381b04SJed Brown   PetscErrorCode ierr;
8488a381b04SJed Brown 
8498a381b04SJed Brown   PetscFunctionBegin;
850d5e6173cSPeter Brune   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
851d5e6173cSPeter Brune   ierr = TSARKIMEXGetVecs(ts,dm,&Z,&Ydot);CHKERRQ(ierr);
852b296d7d5SJed Brown   ierr = VecAXPBYPCZ(Ydot,-shift,shift,0,Z,X);CHKERRQ(ierr); /* Ydot = shift*(X-Z) */
853d5e6173cSPeter Brune   dmsave = ts->dm;
854d5e6173cSPeter Brune   ts->dm = dm;
855d5e6173cSPeter Brune   ierr = TSComputeIFunction(ts,ark->stage_time,X,Ydot,F,ark->imex);CHKERRQ(ierr);
856d5e6173cSPeter Brune   ts->dm = dmsave;
857d5e6173cSPeter Brune   ierr = TSARKIMEXRestoreVecs(ts,dm,&Z,&Ydot);CHKERRQ(ierr);
8588a381b04SJed Brown   PetscFunctionReturn(0);
8598a381b04SJed Brown }
8608a381b04SJed Brown 
8618a381b04SJed Brown #undef __FUNCT__
8628a381b04SJed Brown #define __FUNCT__ "SNESTSFormJacobian_ARKIMEX"
8638a381b04SJed Brown static PetscErrorCode SNESTSFormJacobian_ARKIMEX(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *str,TS ts)
8648a381b04SJed Brown {
8658a381b04SJed Brown   TS_ARKIMEX     *ark = (TS_ARKIMEX*)ts->data;
866d5e6173cSPeter Brune   DM             dm,dmsave;
867d5e6173cSPeter Brune   Vec            Ydot;
868b296d7d5SJed Brown   PetscReal      shift = ark->scoeff / ts->time_step;
8698a381b04SJed Brown   PetscErrorCode ierr;
8708a381b04SJed Brown 
8718a381b04SJed Brown   PetscFunctionBegin;
872d5e6173cSPeter Brune   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
873d5e6173cSPeter Brune   ierr = TSARKIMEXGetVecs(ts,dm,PETSC_NULL,&Ydot);CHKERRQ(ierr);
8748a381b04SJed Brown   /* ark->Ydot has already been computed in SNESTSFormFunction_ARKIMEX (SNES guarantees this) */
875d5e6173cSPeter Brune   dmsave = ts->dm;
876d5e6173cSPeter Brune   ts->dm = dm;
877b296d7d5SJed Brown   ierr = TSComputeIJacobian(ts,ark->stage_time,X,Ydot,shift,A,B,str,ark->imex);CHKERRQ(ierr);
878d5e6173cSPeter Brune   ts->dm = dmsave;
879d5e6173cSPeter Brune   ierr = TSARKIMEXRestoreVecs(ts,dm,PETSC_NULL,&Ydot);CHKERRQ(ierr);
880d5e6173cSPeter Brune   PetscFunctionReturn(0);
881d5e6173cSPeter Brune }
882d5e6173cSPeter Brune 
883d5e6173cSPeter Brune #undef __FUNCT__
884d5e6173cSPeter Brune #define __FUNCT__ "DMCoarsenHook_TSARKIMEX"
885d5e6173cSPeter Brune static PetscErrorCode DMCoarsenHook_TSARKIMEX(DM fine,DM coarse,void *ctx)
886d5e6173cSPeter Brune {
887d5e6173cSPeter Brune 
888d5e6173cSPeter Brune   PetscFunctionBegin;
889d5e6173cSPeter Brune   PetscFunctionReturn(0);
890d5e6173cSPeter Brune }
891d5e6173cSPeter Brune 
892d5e6173cSPeter Brune #undef __FUNCT__
893d5e6173cSPeter Brune #define __FUNCT__ "DMRestrictHook_TSARKIMEX"
894d5e6173cSPeter Brune static PetscErrorCode DMRestrictHook_TSARKIMEX(DM fine,Mat restrct,Vec rscale,Mat inject,DM coarse,void *ctx)
895d5e6173cSPeter Brune {
896d5e6173cSPeter Brune   TS             ts = (TS)ctx;
897d5e6173cSPeter Brune   PetscErrorCode ierr;
898d5e6173cSPeter Brune   Vec            Z,Z_c;
899d5e6173cSPeter Brune 
900d5e6173cSPeter Brune   PetscFunctionBegin;
901d5e6173cSPeter Brune   ierr = TSARKIMEXGetVecs(ts,fine,&Z,PETSC_NULL);CHKERRQ(ierr);
902d5e6173cSPeter Brune   ierr = TSARKIMEXGetVecs(ts,coarse,&Z_c,PETSC_NULL);CHKERRQ(ierr);
903d5e6173cSPeter Brune   ierr = MatRestrict(restrct,Z,Z_c);CHKERRQ(ierr);
904d5e6173cSPeter Brune   ierr = VecPointwiseMult(Z_c,rscale,Z_c);CHKERRQ(ierr);
905d5e6173cSPeter Brune   ierr = TSARKIMEXRestoreVecs(ts,fine,&Z,PETSC_NULL);CHKERRQ(ierr);
906d5e6173cSPeter Brune   ierr = TSARKIMEXRestoreVecs(ts,coarse,&Z_c,PETSC_NULL);CHKERRQ(ierr);
9078a381b04SJed Brown   PetscFunctionReturn(0);
9088a381b04SJed Brown }
9098a381b04SJed Brown 
910*cdb298fcSPeter Brune 
911*cdb298fcSPeter Brune #undef __FUNCT__
912*cdb298fcSPeter Brune #define __FUNCT__ "DMSubDomainHook_TSARKIMEX"
913*cdb298fcSPeter Brune static PetscErrorCode DMSubDomainHook_TSARKIMEX(DM dm,DM subdm,void *ctx)
914*cdb298fcSPeter Brune {
915*cdb298fcSPeter Brune 
916*cdb298fcSPeter Brune   PetscFunctionBegin;
917*cdb298fcSPeter Brune   PetscFunctionReturn(0);
918*cdb298fcSPeter Brune }
919*cdb298fcSPeter Brune 
920*cdb298fcSPeter Brune #undef __FUNCT__
921*cdb298fcSPeter Brune #define __FUNCT__ "DMSubDomainRestrictHook_TSARKIMEX"
922*cdb298fcSPeter Brune static PetscErrorCode DMSubDomainRestrictHook_TSARKIMEX(DM dm,VecScatter gscat,VecScatter lscat,DM subdm,void *ctx)
923*cdb298fcSPeter Brune {
924*cdb298fcSPeter Brune   TS             ts = (TS)ctx;
925*cdb298fcSPeter Brune   PetscErrorCode ierr;
926*cdb298fcSPeter Brune   Vec            Z,Z_c;
927*cdb298fcSPeter Brune 
928*cdb298fcSPeter Brune   PetscFunctionBegin;
929*cdb298fcSPeter Brune   ierr = TSARKIMEXGetVecs(ts,dm,&Z,PETSC_NULL);CHKERRQ(ierr);
930*cdb298fcSPeter Brune   ierr = TSARKIMEXGetVecs(ts,subdm,&Z_c,PETSC_NULL);CHKERRQ(ierr);
931*cdb298fcSPeter Brune 
932*cdb298fcSPeter Brune   ierr = VecScatterBegin(gscat,Z,Z_c,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
933*cdb298fcSPeter Brune   ierr = VecScatterEnd(gscat,Z,Z_c,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
934*cdb298fcSPeter Brune 
935*cdb298fcSPeter Brune   ierr = TSARKIMEXRestoreVecs(ts,dm,&Z,PETSC_NULL);CHKERRQ(ierr);
936*cdb298fcSPeter Brune   ierr = TSARKIMEXRestoreVecs(ts,subdm,&Z_c,PETSC_NULL);CHKERRQ(ierr);
937*cdb298fcSPeter Brune   PetscFunctionReturn(0);
938*cdb298fcSPeter Brune }
939*cdb298fcSPeter Brune 
9408a381b04SJed Brown #undef __FUNCT__
9418a381b04SJed Brown #define __FUNCT__ "TSSetUp_ARKIMEX"
9428a381b04SJed Brown static PetscErrorCode TSSetUp_ARKIMEX(TS ts)
9438a381b04SJed Brown {
9448a381b04SJed Brown   TS_ARKIMEX     *ark = (TS_ARKIMEX*)ts->data;
945f2c2a1b9SBarry Smith   ARKTableau     tab;
946f2c2a1b9SBarry Smith   PetscInt       s;
9478a381b04SJed Brown   PetscErrorCode ierr;
948d5e6173cSPeter Brune   DM             dm;
949f9c1d6abSBarry Smith 
9508a381b04SJed Brown   PetscFunctionBegin;
9518a381b04SJed Brown   if (!ark->tableau) {
952e24355feSJed Brown     ierr = TSARKIMEXSetType(ts,TSARKIMEXDefault);CHKERRQ(ierr);
9538a381b04SJed Brown   }
954f2c2a1b9SBarry Smith   tab  = ark->tableau;
955f2c2a1b9SBarry Smith   s    = tab->s;
9568a381b04SJed Brown   ierr = VecDuplicateVecs(ts->vec_sol,s,&ark->Y);CHKERRQ(ierr);
9578a381b04SJed Brown   ierr = VecDuplicateVecs(ts->vec_sol,s,&ark->YdotI);CHKERRQ(ierr);
9588a381b04SJed Brown   ierr = VecDuplicateVecs(ts->vec_sol,s,&ark->YdotRHS);CHKERRQ(ierr);
9598a381b04SJed Brown   ierr = VecDuplicate(ts->vec_sol,&ark->Ydot);CHKERRQ(ierr);
9608a381b04SJed Brown   ierr = VecDuplicate(ts->vec_sol,&ark->Work);CHKERRQ(ierr);
9618a381b04SJed Brown   ierr = VecDuplicate(ts->vec_sol,&ark->Z);CHKERRQ(ierr);
9628a381b04SJed Brown   ierr = PetscMalloc(s*sizeof(ark->work[0]),&ark->work);CHKERRQ(ierr);
963d5e6173cSPeter Brune   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
964d5e6173cSPeter Brune   if (dm) {
965d5e6173cSPeter Brune     ierr = DMCoarsenHookAdd(dm,DMCoarsenHook_TSARKIMEX,DMRestrictHook_TSARKIMEX,ts);CHKERRQ(ierr);
966*cdb298fcSPeter Brune     ierr = DMSubDomainHookAdd(dm,DMSubDomainHook_TSARKIMEX,DMSubDomainRestrictHook_TSARKIMEX,ts);CHKERRQ(ierr);
967d5e6173cSPeter Brune   }
9688a381b04SJed Brown   PetscFunctionReturn(0);
9698a381b04SJed Brown }
9708a381b04SJed Brown /*------------------------------------------------------------*/
9718a381b04SJed Brown 
9728a381b04SJed Brown #undef __FUNCT__
9738a381b04SJed Brown #define __FUNCT__ "TSSetFromOptions_ARKIMEX"
9748a381b04SJed Brown static PetscErrorCode TSSetFromOptions_ARKIMEX(TS ts)
9758a381b04SJed Brown {
9764cc180ffSJed Brown   TS_ARKIMEX     *ark = (TS_ARKIMEX*)ts->data;
9778a381b04SJed Brown   PetscErrorCode ierr;
9788a381b04SJed Brown   char           arktype[256];
9798a381b04SJed Brown 
9808a381b04SJed Brown   PetscFunctionBegin;
9818a381b04SJed Brown   ierr = PetscOptionsHead("ARKIMEX ODE solver options");CHKERRQ(ierr);
9828a381b04SJed Brown   {
9838a381b04SJed Brown     ARKTableauLink link;
9848a381b04SJed Brown     PetscInt       count,choice;
9858a381b04SJed Brown     PetscBool      flg;
9868a381b04SJed Brown     const char     **namelist;
9878caf3d72SBarry Smith     ierr = PetscStrncpy(arktype,TSARKIMEXDefault,sizeof(arktype));CHKERRQ(ierr);
9888a381b04SJed Brown     for (link=ARKTableauList,count=0; link; link=link->next,count++) ;
9898a381b04SJed Brown     ierr = PetscMalloc(count*sizeof(char*),&namelist);CHKERRQ(ierr);
9908a381b04SJed Brown     for (link=ARKTableauList,count=0; link; link=link->next,count++) namelist[count] = link->tab.name;
9918a381b04SJed Brown     ierr = PetscOptionsEList("-ts_arkimex_type","Family of ARK IMEX method","TSARKIMEXSetType",(const char*const*)namelist,count,arktype,&choice,&flg);CHKERRQ(ierr);
9928a381b04SJed Brown     ierr = TSARKIMEXSetType(ts,flg ? namelist[choice] : arktype);CHKERRQ(ierr);
9938a381b04SJed Brown     ierr = PetscFree(namelist);CHKERRQ(ierr);
9944cc180ffSJed Brown     flg = (PetscBool)!ark->imex;
9954cc180ffSJed Brown     ierr = PetscOptionsBool("-ts_arkimex_fully_implicit","Solve the problem fully implicitly","TSARKIMEXSetFullyImplicit",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
9964cc180ffSJed Brown     ark->imex = (PetscBool)!flg;
997d52bd9f3SBarry Smith     ierr = SNESSetFromOptions(ts->snes);CHKERRQ(ierr);
9988a381b04SJed Brown   }
9998a381b04SJed Brown   ierr = PetscOptionsTail();CHKERRQ(ierr);
10008a381b04SJed Brown   PetscFunctionReturn(0);
10018a381b04SJed Brown }
10028a381b04SJed Brown 
10038a381b04SJed Brown #undef __FUNCT__
10048a381b04SJed Brown #define __FUNCT__ "PetscFormatRealArray"
10058a381b04SJed Brown static PetscErrorCode PetscFormatRealArray(char buf[],size_t len,const char *fmt,PetscInt n,const PetscReal x[])
10068a381b04SJed Brown {
1007257d2499SJed Brown   PetscErrorCode ierr;
1008f1d86077SJed Brown   PetscInt       i;
1009f1d86077SJed Brown   size_t         left,count;
10108a381b04SJed Brown   char           *p;
10118a381b04SJed Brown 
10128a381b04SJed Brown   PetscFunctionBegin;
1013f1d86077SJed Brown   for (i=0,p=buf,left=len; i<n; i++) {
1014f1d86077SJed Brown     ierr = PetscSNPrintfCount(p,left,fmt,&count,x[i]);CHKERRQ(ierr);
10158a381b04SJed Brown     if (count >= left) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Insufficient space in buffer");
10168a381b04SJed Brown     left -= count;
10178a381b04SJed Brown     p += count;
10188a381b04SJed Brown     *p++ = ' ';
10198a381b04SJed Brown   }
10208a381b04SJed Brown   p[i ? 0 : -1] = 0;
10218a381b04SJed Brown   PetscFunctionReturn(0);
10228a381b04SJed Brown }
10238a381b04SJed Brown 
10248a381b04SJed Brown #undef __FUNCT__
10258a381b04SJed Brown #define __FUNCT__ "TSView_ARKIMEX"
10268a381b04SJed Brown static PetscErrorCode TSView_ARKIMEX(TS ts,PetscViewer viewer)
10278a381b04SJed Brown {
10288a381b04SJed Brown   TS_ARKIMEX     *ark = (TS_ARKIMEX*)ts->data;
10298a381b04SJed Brown   ARKTableau     tab = ark->tableau;
10308a381b04SJed Brown   PetscBool      iascii;
10318a381b04SJed Brown   PetscErrorCode ierr;
1032559eea31SJed Brown   TSAdapt        adapt;
10338a381b04SJed Brown 
10348a381b04SJed Brown   PetscFunctionBegin;
1035251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
10368a381b04SJed Brown   if (iascii) {
103719fd82e9SBarry Smith     TSARKIMEXType arktype;
10388a381b04SJed Brown     char buf[512];
10398a381b04SJed Brown     ierr = TSARKIMEXGetType(ts,&arktype);CHKERRQ(ierr);
10408a381b04SJed Brown     ierr = PetscViewerASCIIPrintf(viewer,"  ARK IMEX %s\n",arktype);CHKERRQ(ierr);
10418caf3d72SBarry Smith     ierr = PetscFormatRealArray(buf,sizeof(buf),"% 8.6f",tab->s,tab->ct);CHKERRQ(ierr);
104231f6fcc0SJed Brown     ierr = PetscViewerASCIIPrintf(viewer,"  Stiff abscissa       ct = %s\n",buf);CHKERRQ(ierr);
10438caf3d72SBarry Smith     ierr = PetscFormatRealArray(buf,sizeof(buf),"% 8.6f",tab->s,tab->c);CHKERRQ(ierr);
104431f6fcc0SJed Brown     ierr = PetscViewerASCIIPrintf(viewer,"  Nonstiff abscissa     c = %s\n",buf);CHKERRQ(ierr);
10458a381b04SJed Brown   }
1046ad6bc421SBarry Smith   ierr = TSGetTSAdapt(ts,&adapt);CHKERRQ(ierr);
1047559eea31SJed Brown   ierr = TSAdaptView(adapt,viewer);CHKERRQ(ierr);
1048d52bd9f3SBarry Smith   ierr = SNESView(ts->snes,viewer);CHKERRQ(ierr);
10498a381b04SJed Brown   PetscFunctionReturn(0);
10508a381b04SJed Brown }
10518a381b04SJed Brown 
10528a381b04SJed Brown #undef __FUNCT__
1053f2c2a1b9SBarry Smith #define __FUNCT__ "TSLoad_ARKIMEX"
1054f2c2a1b9SBarry Smith static PetscErrorCode TSLoad_ARKIMEX(TS ts,PetscViewer viewer)
1055f2c2a1b9SBarry Smith {
1056f2c2a1b9SBarry Smith   PetscErrorCode ierr;
1057f2c2a1b9SBarry Smith   SNES           snes;
1058ad6bc421SBarry Smith   TSAdapt        tsadapt;
1059f2c2a1b9SBarry Smith 
1060f2c2a1b9SBarry Smith   PetscFunctionBegin;
1061ad6bc421SBarry Smith   ierr = TSGetTSAdapt(ts,&tsadapt);CHKERRQ(ierr);
1062ad6bc421SBarry Smith   ierr = TSAdaptLoad(tsadapt,viewer);CHKERRQ(ierr);
1063f2c2a1b9SBarry Smith   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
1064f2c2a1b9SBarry Smith   ierr = SNESLoad(snes,viewer);CHKERRQ(ierr);
1065ad6bc421SBarry Smith   /* function and Jacobian context for SNES when used with TS is always ts object */
1066ad6bc421SBarry Smith   ierr = SNESSetFunction(snes,PETSC_NULL,PETSC_NULL,ts);CHKERRQ(ierr);
1067ad6bc421SBarry Smith   ierr = SNESSetJacobian(snes,PETSC_NULL,PETSC_NULL,PETSC_NULL,ts);CHKERRQ(ierr);
1068f2c2a1b9SBarry Smith   PetscFunctionReturn(0);
1069f2c2a1b9SBarry Smith }
1070f2c2a1b9SBarry Smith 
1071f2c2a1b9SBarry Smith #undef __FUNCT__
10728a381b04SJed Brown #define __FUNCT__ "TSARKIMEXSetType"
10738a381b04SJed Brown /*@C
10748a381b04SJed Brown   TSARKIMEXSetType - Set the type of ARK IMEX scheme
10758a381b04SJed Brown 
10768a381b04SJed Brown   Logically collective
10778a381b04SJed Brown 
10788a381b04SJed Brown   Input Parameter:
10798a381b04SJed Brown +  ts - timestepping context
10808a381b04SJed Brown -  arktype - type of ARK-IMEX scheme
10818a381b04SJed Brown 
10828a381b04SJed Brown   Level: intermediate
10838a381b04SJed Brown 
1084020d8f30SJed Brown .seealso: TSARKIMEXGetType(), TSARKIMEX, TSARKIMEX2D, TSARKIMEX2E, TSARKIMEXPRSSP2, TSARKIMEX3, TSARKIMEXBPR3, TSARKIMEXARS443, TSARKIMEX4, TSARKIMEX5
10858a381b04SJed Brown @*/
108619fd82e9SBarry Smith PetscErrorCode TSARKIMEXSetType(TS ts,TSARKIMEXType arktype)
10878a381b04SJed Brown {
10888a381b04SJed Brown   PetscErrorCode ierr;
10898a381b04SJed Brown 
10908a381b04SJed Brown   PetscFunctionBegin;
10918a381b04SJed Brown   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
109219fd82e9SBarry Smith   ierr = PetscTryMethod(ts,"TSARKIMEXSetType_C",(TS,TSARKIMEXType),(ts,arktype));CHKERRQ(ierr);
10938a381b04SJed Brown   PetscFunctionReturn(0);
10948a381b04SJed Brown }
10958a381b04SJed Brown 
10968a381b04SJed Brown #undef __FUNCT__
10978a381b04SJed Brown #define __FUNCT__ "TSARKIMEXGetType"
10988a381b04SJed Brown /*@C
10998a381b04SJed Brown   TSARKIMEXGetType - Get the type of ARK IMEX scheme
11008a381b04SJed Brown 
11018a381b04SJed Brown   Logically collective
11028a381b04SJed Brown 
11038a381b04SJed Brown   Input Parameter:
11048a381b04SJed Brown .  ts - timestepping context
11058a381b04SJed Brown 
11068a381b04SJed Brown   Output Parameter:
11078a381b04SJed Brown .  arktype - type of ARK-IMEX scheme
11088a381b04SJed Brown 
11098a381b04SJed Brown   Level: intermediate
11108a381b04SJed Brown 
11118a381b04SJed Brown .seealso: TSARKIMEXGetType()
11128a381b04SJed Brown @*/
111319fd82e9SBarry Smith PetscErrorCode TSARKIMEXGetType(TS ts,TSARKIMEXType *arktype)
11148a381b04SJed Brown {
11158a381b04SJed Brown   PetscErrorCode ierr;
11168a381b04SJed Brown 
11178a381b04SJed Brown   PetscFunctionBegin;
11188a381b04SJed Brown   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
111919fd82e9SBarry Smith   ierr = PetscUseMethod(ts,"TSARKIMEXGetType_C",(TS,TSARKIMEXType*),(ts,arktype));CHKERRQ(ierr);
11208a381b04SJed Brown   PetscFunctionReturn(0);
11218a381b04SJed Brown }
11228a381b04SJed Brown 
11234cc180ffSJed Brown #undef __FUNCT__
11244cc180ffSJed Brown #define __FUNCT__ "TSARKIMEXSetFullyImplicit"
11254cc180ffSJed Brown /*@C
11264cc180ffSJed Brown   TSARKIMEXSetFullyImplicit - Solve both parts of the equation implicitly
11274cc180ffSJed Brown 
11284cc180ffSJed Brown   Logically collective
11294cc180ffSJed Brown 
11304cc180ffSJed Brown   Input Parameter:
11314cc180ffSJed Brown +  ts - timestepping context
11324cc180ffSJed Brown -  flg - PETSC_TRUE for fully implicit
11334cc180ffSJed Brown 
11344cc180ffSJed Brown   Level: intermediate
11354cc180ffSJed Brown 
11364cc180ffSJed Brown .seealso: TSARKIMEXGetType()
11374cc180ffSJed Brown @*/
11384cc180ffSJed Brown PetscErrorCode TSARKIMEXSetFullyImplicit(TS ts,PetscBool flg)
11394cc180ffSJed Brown {
11404cc180ffSJed Brown   PetscErrorCode ierr;
11414cc180ffSJed Brown 
11424cc180ffSJed Brown   PetscFunctionBegin;
11434cc180ffSJed Brown   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
11444cc180ffSJed Brown   ierr = PetscTryMethod(ts,"TSARKIMEXSetFullyImplicit_C",(TS,PetscBool),(ts,flg));CHKERRQ(ierr);
11454cc180ffSJed Brown   PetscFunctionReturn(0);
11464cc180ffSJed Brown }
11474cc180ffSJed Brown 
11488a381b04SJed Brown EXTERN_C_BEGIN
11498a381b04SJed Brown #undef __FUNCT__
11508a381b04SJed Brown #define __FUNCT__ "TSARKIMEXGetType_ARKIMEX"
115119fd82e9SBarry Smith PetscErrorCode  TSARKIMEXGetType_ARKIMEX(TS ts,TSARKIMEXType *arktype)
11528a381b04SJed Brown {
11538a381b04SJed Brown   TS_ARKIMEX *ark = (TS_ARKIMEX*)ts->data;
11548a381b04SJed Brown   PetscErrorCode ierr;
11558a381b04SJed Brown 
11568a381b04SJed Brown   PetscFunctionBegin;
1157f2c2a1b9SBarry Smith   if (!ark->tableau) {
1158f2c2a1b9SBarry Smith     ierr = TSARKIMEXSetType(ts,TSARKIMEXDefault);CHKERRQ(ierr);
1159f2c2a1b9SBarry Smith   }
11608a381b04SJed Brown   *arktype = ark->tableau->name;
11618a381b04SJed Brown   PetscFunctionReturn(0);
11628a381b04SJed Brown }
11638a381b04SJed Brown #undef __FUNCT__
11648a381b04SJed Brown #define __FUNCT__ "TSARKIMEXSetType_ARKIMEX"
116519fd82e9SBarry Smith PetscErrorCode  TSARKIMEXSetType_ARKIMEX(TS ts,TSARKIMEXType arktype)
11668a381b04SJed Brown {
11678a381b04SJed Brown   TS_ARKIMEX *ark = (TS_ARKIMEX*)ts->data;
11688a381b04SJed Brown   PetscErrorCode ierr;
11698a381b04SJed Brown   PetscBool match;
11708a381b04SJed Brown   ARKTableauLink link;
11718a381b04SJed Brown 
11728a381b04SJed Brown   PetscFunctionBegin;
11738a381b04SJed Brown   if (ark->tableau) {
11748a381b04SJed Brown     ierr = PetscStrcmp(ark->tableau->name,arktype,&match);CHKERRQ(ierr);
11758a381b04SJed Brown     if (match) PetscFunctionReturn(0);
11768a381b04SJed Brown   }
11778a381b04SJed Brown   for (link = ARKTableauList; link; link=link->next) {
11788a381b04SJed Brown     ierr = PetscStrcmp(link->tab.name,arktype,&match);CHKERRQ(ierr);
11798a381b04SJed Brown     if (match) {
11808a381b04SJed Brown       ierr = TSReset_ARKIMEX(ts);CHKERRQ(ierr);
11818a381b04SJed Brown       ark->tableau = &link->tab;
11828a381b04SJed Brown       PetscFunctionReturn(0);
11838a381b04SJed Brown     }
11848a381b04SJed Brown   }
11858a381b04SJed Brown   SETERRQ1(((PetscObject)ts)->comm,PETSC_ERR_ARG_UNKNOWN_TYPE,"Could not find '%s'",arktype);
11868a381b04SJed Brown   PetscFunctionReturn(0);
11878a381b04SJed Brown }
11884cc180ffSJed Brown #undef __FUNCT__
11894cc180ffSJed Brown #define __FUNCT__ "TSARKIMEXSetFullyImplicit_ARKIMEX"
11904cc180ffSJed Brown PetscErrorCode  TSARKIMEXSetFullyImplicit_ARKIMEX(TS ts,PetscBool flg)
11914cc180ffSJed Brown {
11924cc180ffSJed Brown   TS_ARKIMEX *ark = (TS_ARKIMEX*)ts->data;
11934cc180ffSJed Brown 
11944cc180ffSJed Brown   PetscFunctionBegin;
11954cc180ffSJed Brown   ark->imex = (PetscBool)!flg;
11964cc180ffSJed Brown   PetscFunctionReturn(0);
11974cc180ffSJed Brown }
11988a381b04SJed Brown EXTERN_C_END
11998a381b04SJed Brown 
12008a381b04SJed Brown /* ------------------------------------------------------------ */
12018a381b04SJed Brown /*MC
1202a4386c9eSJed Brown       TSARKIMEX - ODE and DAE solver using Additive Runge-Kutta IMEX schemes
12038a381b04SJed Brown 
1204fca742c7SJed Brown   These methods are intended for problems with well-separated time scales, especially when a slow scale is strongly
1205fca742c7SJed Brown   nonlinear such that it is expensive to solve with a fully implicit method. The user should provide the stiff part
1206fca742c7SJed Brown   of the equation using TSSetIFunction() and the non-stiff part with TSSetRHSFunction().
1207fca742c7SJed Brown 
1208fca742c7SJed Brown   Notes:
1209a4386c9eSJed Brown   The default is TSARKIMEX3, it can be changed with TSARKIMEXSetType() or -ts_arkimex_type
1210c8058688SBarry Smith 
1211a4386c9eSJed Brown   Methods with an explicit stage can only be used with ODE in which the stiff part G(t,X,Xdot) has the form Xdot + Ghat(t,X).
1212fca742c7SJed Brown 
12138a381b04SJed Brown   Level: beginner
12148a381b04SJed Brown 
1215c8058688SBarry Smith .seealso:  TSCreate(), TS, TSSetType(), TSARKIMEXSetType(), TSARKIMEXGetType(), TSARKIMEXSetFullyImplicit(), TSARKIMEX2D, TTSARKIMEX2E, TSARKIMEX3,
1216a4386c9eSJed Brown            TSARKIMEX4, TSARKIMEX5, TSARKIMEXPRSSP2, TSARKIMEXBPR3, TSARKIMEXType, TSARKIMEXRegister()
12178a381b04SJed Brown 
12188a381b04SJed Brown M*/
12198a381b04SJed Brown EXTERN_C_BEGIN
12208a381b04SJed Brown #undef __FUNCT__
12218a381b04SJed Brown #define __FUNCT__ "TSCreate_ARKIMEX"
12228a381b04SJed Brown PetscErrorCode  TSCreate_ARKIMEX(TS ts)
12238a381b04SJed Brown {
12248a381b04SJed Brown   TS_ARKIMEX     *th;
12258a381b04SJed Brown   PetscErrorCode ierr;
12268a381b04SJed Brown 
12278a381b04SJed Brown   PetscFunctionBegin;
12288a381b04SJed Brown #if !defined(PETSC_USE_DYNAMIC_LIBRARIES)
12298a381b04SJed Brown   ierr = TSARKIMEXInitializePackage(PETSC_NULL);CHKERRQ(ierr);
12308a381b04SJed Brown #endif
12318a381b04SJed Brown 
12328a381b04SJed Brown   ts->ops->reset          = TSReset_ARKIMEX;
12338a381b04SJed Brown   ts->ops->destroy        = TSDestroy_ARKIMEX;
12348a381b04SJed Brown   ts->ops->view           = TSView_ARKIMEX;
1235f2c2a1b9SBarry Smith   ts->ops->load           = TSLoad_ARKIMEX;
12368a381b04SJed Brown   ts->ops->setup          = TSSetUp_ARKIMEX;
12378a381b04SJed Brown   ts->ops->step           = TSStep_ARKIMEX;
1238cd652676SJed Brown   ts->ops->interpolate    = TSInterpolate_ARKIMEX;
1239108c343cSJed Brown   ts->ops->evaluatestep   = TSEvaluateStep_ARKIMEX;
12408a381b04SJed Brown   ts->ops->setfromoptions = TSSetFromOptions_ARKIMEX;
12418a381b04SJed Brown   ts->ops->snesfunction   = SNESTSFormFunction_ARKIMEX;
12428a381b04SJed Brown   ts->ops->snesjacobian   = SNESTSFormJacobian_ARKIMEX;
12438a381b04SJed Brown 
12448a381b04SJed Brown   ierr = PetscNewLog(ts,TS_ARKIMEX,&th);CHKERRQ(ierr);
12458a381b04SJed Brown   ts->data = (void*)th;
12464cc180ffSJed Brown   th->imex = PETSC_TRUE;
12478a381b04SJed Brown 
12488a381b04SJed Brown   ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSARKIMEXGetType_C","TSARKIMEXGetType_ARKIMEX",TSARKIMEXGetType_ARKIMEX);CHKERRQ(ierr);
12498a381b04SJed Brown   ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSARKIMEXSetType_C","TSARKIMEXSetType_ARKIMEX",TSARKIMEXSetType_ARKIMEX);CHKERRQ(ierr);
12504cc180ffSJed Brown   ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSARKIMEXSetFullyImplicit_C","TSARKIMEXSetFullyImplicit_ARKIMEX",TSARKIMEXSetFullyImplicit_ARKIMEX);CHKERRQ(ierr);
12518a381b04SJed Brown   PetscFunctionReturn(0);
12528a381b04SJed Brown }
12538a381b04SJed Brown EXTERN_C_END
1254