12302aa1bSDebojyoti Ghosh /* 22302aa1bSDebojyoti Ghosh Code for time stepping with the General Linear with Error Estimation method 32302aa1bSDebojyoti Ghosh 42302aa1bSDebojyoti Ghosh Notes: 52302aa1bSDebojyoti Ghosh The general system is written as 62302aa1bSDebojyoti Ghosh 72302aa1bSDebojyoti Ghosh Udot = F(t,U) 82302aa1bSDebojyoti Ghosh 92302aa1bSDebojyoti Ghosh */ 102302aa1bSDebojyoti Ghosh #include <petsc/private/tsimpl.h> /*I "petscts.h" I*/ 112302aa1bSDebojyoti Ghosh #include <petscdm.h> 122302aa1bSDebojyoti Ghosh 13642f3702SEmil Constantinescu static PetscBool cited = PETSC_FALSE; 149371c9d4SSatish Balay static const char citation[] = "@ARTICLE{Constantinescu_TR2016b,\n" 15642f3702SEmil Constantinescu " author = {Constantinescu, E.M.},\n" 16642f3702SEmil Constantinescu " title = {Estimating Global Errors in Time Stepping},\n" 17642f3702SEmil Constantinescu " journal = {ArXiv e-prints},\n" 18642f3702SEmil Constantinescu " year = 2016,\n" 19642f3702SEmil Constantinescu " adsurl = {http://adsabs.harvard.edu/abs/2015arXiv150305166C}\n}\n"; 20642f3702SEmil Constantinescu 212302aa1bSDebojyoti Ghosh static TSGLEEType TSGLEEDefaultType = TSGLEE35; 222302aa1bSDebojyoti Ghosh static PetscBool TSGLEERegisterAllCalled; 232302aa1bSDebojyoti Ghosh static PetscBool TSGLEEPackageInitialized; 242302aa1bSDebojyoti Ghosh static PetscInt explicit_stage_time_id; 252302aa1bSDebojyoti Ghosh 262302aa1bSDebojyoti Ghosh typedef struct _GLEETableau *GLEETableau; 272302aa1bSDebojyoti Ghosh struct _GLEETableau { 282302aa1bSDebojyoti Ghosh char *name; 292302aa1bSDebojyoti Ghosh PetscInt order; /* Classical approximation order of the method i*/ 302302aa1bSDebojyoti Ghosh PetscInt s; /* Number of stages */ 312302aa1bSDebojyoti Ghosh PetscInt r; /* Number of steps */ 322302aa1bSDebojyoti Ghosh PetscReal gamma; /* LTE ratio */ 332302aa1bSDebojyoti Ghosh PetscReal *A, *B, *U, *V, *S, *F, *c; /* Tableau */ 342302aa1bSDebojyoti Ghosh PetscReal *Fembed; /* Embedded final method coefficients */ 35fd96ebc2SDebojyoti Ghosh PetscReal *Ferror; /* Coefficients for computing error */ 3657df6a1bSDebojyoti Ghosh PetscReal *Serror; /* Coefficients for initializing the error */ 372302aa1bSDebojyoti Ghosh PetscInt pinterp; /* Interpolation order */ 382302aa1bSDebojyoti Ghosh PetscReal *binterp; /* Interpolation coefficients */ 392302aa1bSDebojyoti Ghosh PetscReal ccfl; /* Placeholder for CFL coefficient relative to forward Euler */ 402302aa1bSDebojyoti Ghosh }; 412302aa1bSDebojyoti Ghosh typedef struct _GLEETableauLink *GLEETableauLink; 422302aa1bSDebojyoti Ghosh struct _GLEETableauLink { 432302aa1bSDebojyoti Ghosh struct _GLEETableau tab; 442302aa1bSDebojyoti Ghosh GLEETableauLink next; 452302aa1bSDebojyoti Ghosh }; 462302aa1bSDebojyoti Ghosh static GLEETableauLink GLEETableauList; 472302aa1bSDebojyoti Ghosh 482302aa1bSDebojyoti Ghosh typedef struct { 492302aa1bSDebojyoti Ghosh GLEETableau tableau; 502302aa1bSDebojyoti Ghosh Vec *Y; /* Solution vector (along with auxiliary solution y~ or eps) */ 512302aa1bSDebojyoti Ghosh Vec *X; /* Temporary solution vector */ 522302aa1bSDebojyoti Ghosh Vec *YStage; /* Stage values */ 532302aa1bSDebojyoti Ghosh Vec *YdotStage; /* Stage right hand side */ 542302aa1bSDebojyoti Ghosh Vec W; /* Right-hand-side for implicit stage solve */ 552302aa1bSDebojyoti Ghosh Vec Ydot; /* Work vector holding Ydot during residual evaluation */ 560a01e1b2SEmil Constantinescu Vec yGErr; /* Vector holding the global error after a step is completed */ 57ec0e3ee2SEmil Constantinescu PetscScalar *swork; /* Scalar work (size of the number of stages)*/ 58ec0e3ee2SEmil Constantinescu PetscScalar *rwork; /* Scalar work (size of the number of steps)*/ 592302aa1bSDebojyoti Ghosh PetscReal scoeff; /* shift = scoeff/dt */ 602302aa1bSDebojyoti Ghosh PetscReal stage_time; 612302aa1bSDebojyoti Ghosh TSStepStatus status; 622302aa1bSDebojyoti Ghosh } TS_GLEE; 632302aa1bSDebojyoti Ghosh 642302aa1bSDebojyoti Ghosh /*MC 652302aa1bSDebojyoti Ghosh TSGLEE23 - Second order three stage GLEE method 662302aa1bSDebojyoti Ghosh 672302aa1bSDebojyoti Ghosh This method has three stages. 682302aa1bSDebojyoti Ghosh s = 3, r = 2 692302aa1bSDebojyoti Ghosh 702302aa1bSDebojyoti Ghosh Level: advanced 712302aa1bSDebojyoti Ghosh 72db781477SPatrick Sanan .seealso: `TSGLEE` 7336c34d14SEmil Constantinescu M*/ 742302aa1bSDebojyoti Ghosh /*MC 752302aa1bSDebojyoti Ghosh TSGLEE24 - Second order four stage GLEE method 762302aa1bSDebojyoti Ghosh 772302aa1bSDebojyoti Ghosh This method has four stages. 782302aa1bSDebojyoti Ghosh s = 4, r = 2 792302aa1bSDebojyoti Ghosh 802302aa1bSDebojyoti Ghosh Level: advanced 812302aa1bSDebojyoti Ghosh 82db781477SPatrick Sanan .seealso: `TSGLEE` 8336c34d14SEmil Constantinescu M*/ 842302aa1bSDebojyoti Ghosh /*MC 852302aa1bSDebojyoti Ghosh TSGLEE25i - Second order five stage GLEE method 862302aa1bSDebojyoti Ghosh 872302aa1bSDebojyoti Ghosh This method has five stages. 882302aa1bSDebojyoti Ghosh s = 5, r = 2 892302aa1bSDebojyoti Ghosh 902302aa1bSDebojyoti Ghosh Level: advanced 912302aa1bSDebojyoti Ghosh 92db781477SPatrick Sanan .seealso: `TSGLEE` 9336c34d14SEmil Constantinescu M*/ 942302aa1bSDebojyoti Ghosh /*MC 952302aa1bSDebojyoti Ghosh TSGLEE35 - Third order five stage GLEE method 962302aa1bSDebojyoti Ghosh 972302aa1bSDebojyoti Ghosh This method has five stages. 982302aa1bSDebojyoti Ghosh s = 5, r = 2 992302aa1bSDebojyoti Ghosh 1002302aa1bSDebojyoti Ghosh Level: advanced 1012302aa1bSDebojyoti Ghosh 102db781477SPatrick Sanan .seealso: `TSGLEE` 10336c34d14SEmil Constantinescu M*/ 1042302aa1bSDebojyoti Ghosh /*MC 1052302aa1bSDebojyoti Ghosh TSGLEEEXRK2A - Second order six stage GLEE method 1062302aa1bSDebojyoti Ghosh 1072302aa1bSDebojyoti Ghosh This method has six stages. 1082302aa1bSDebojyoti Ghosh s = 6, r = 2 1092302aa1bSDebojyoti Ghosh 1102302aa1bSDebojyoti Ghosh Level: advanced 1112302aa1bSDebojyoti Ghosh 112db781477SPatrick Sanan .seealso: `TSGLEE` 11336c34d14SEmil Constantinescu M*/ 1142302aa1bSDebojyoti Ghosh /*MC 1152302aa1bSDebojyoti Ghosh TSGLEERK32G1 - Third order eight stage GLEE method 1162302aa1bSDebojyoti Ghosh 1172302aa1bSDebojyoti Ghosh This method has eight stages. 1182302aa1bSDebojyoti Ghosh s = 8, r = 2 1192302aa1bSDebojyoti Ghosh 1202302aa1bSDebojyoti Ghosh Level: advanced 1212302aa1bSDebojyoti Ghosh 122db781477SPatrick Sanan .seealso: `TSGLEE` 12336c34d14SEmil Constantinescu M*/ 1242302aa1bSDebojyoti Ghosh /*MC 1252302aa1bSDebojyoti Ghosh TSGLEERK285EX - Second order nine stage GLEE method 1262302aa1bSDebojyoti Ghosh 1272302aa1bSDebojyoti Ghosh This method has nine stages. 1282302aa1bSDebojyoti Ghosh s = 9, r = 2 1292302aa1bSDebojyoti Ghosh 1302302aa1bSDebojyoti Ghosh Level: advanced 1312302aa1bSDebojyoti Ghosh 132db781477SPatrick Sanan .seealso: `TSGLEE` 13336c34d14SEmil Constantinescu M*/ 1342302aa1bSDebojyoti Ghosh 1352302aa1bSDebojyoti Ghosh /*@C 1362302aa1bSDebojyoti Ghosh TSGLEERegisterAll - Registers all of the General Linear with Error Estimation methods in TSGLEE 1372302aa1bSDebojyoti Ghosh 1382302aa1bSDebojyoti Ghosh Not Collective, but should be called by all processes which will need the schemes to be registered 1392302aa1bSDebojyoti Ghosh 1402302aa1bSDebojyoti Ghosh Level: advanced 1412302aa1bSDebojyoti Ghosh 142db781477SPatrick Sanan .seealso: `TSGLEERegisterDestroy()` 1432302aa1bSDebojyoti Ghosh @*/ 144*d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGLEERegisterAll(void) 145*d71ae5a4SJacob Faibussowitsch { 1462302aa1bSDebojyoti Ghosh PetscFunctionBegin; 1472302aa1bSDebojyoti Ghosh if (TSGLEERegisterAllCalled) PetscFunctionReturn(0); 1482302aa1bSDebojyoti Ghosh TSGLEERegisterAllCalled = PETSC_TRUE; 1492302aa1bSDebojyoti Ghosh 1502302aa1bSDebojyoti Ghosh { 151b1fbfd33SSatish Balay #define GAMMA 0.5 1522302aa1bSDebojyoti Ghosh /* y-eps form */ 1539371c9d4SSatish Balay const PetscInt p = 1, s = 3, r = 2; 1549371c9d4SSatish Balay const PetscReal A[3][3] = 1559371c9d4SSatish Balay { 1569371c9d4SSatish Balay {1.0, 0, 0 }, 1579371c9d4SSatish Balay {0, 0.5, 0 }, 1589371c9d4SSatish Balay {0, 0.5, 0.5} 1599371c9d4SSatish Balay }, 1609371c9d4SSatish Balay B[2][3] = {{1.0, 0, 0}, {-2.0, 1.0, 1.0}}, U[3][2] = {{1.0, 0}, {1.0, 0.5}, {1.0, 0.5}}, V[2][2] = {{1, 0}, {0, 1}}, S[2] = {1, 0}, F[2] = {1, 0}, Fembed[2] = {1, 1 - GAMMA}, Ferror[2] = {0, 1}, Serror[2] = {1, 0}; 1619566063dSJacob Faibussowitsch PetscCall(TSGLEERegister(TSGLEEi1, p, s, r, GAMMA, &A[0][0], &B[0][0], &U[0][0], &V[0][0], S, F, NULL, Fembed, Ferror, Serror, 0, NULL)); 162ab8c5912SEmil Constantinescu } 163ab8c5912SEmil Constantinescu { 164b1fbfd33SSatish Balay #undef GAMMA 165b1fbfd33SSatish Balay #define GAMMA 0.0 166ab8c5912SEmil Constantinescu /* y-eps form */ 1679371c9d4SSatish Balay const PetscInt p = 2, s = 3, r = 2; 1689371c9d4SSatish Balay const PetscReal A[3][3] = 1699371c9d4SSatish Balay { 1709371c9d4SSatish Balay {0, 0, 0}, 1719371c9d4SSatish Balay {1, 0, 0}, 1729371c9d4SSatish Balay {0.25, 0.25, 0} 1739371c9d4SSatish Balay }, 1749371c9d4SSatish Balay B[2][3] = {{1.0 / 12.0, 1.0 / 12.0, 5.0 / 6.0}, {1.0 / 12.0, 1.0 / 12.0, -1.0 / 6.0}}, U[3][2] = {{1, 0}, {1, 10}, {1, -1}}, V[2][2] = {{1, 0}, {0, 1}}, S[2] = {1, 0}, F[2] = {1, 0}, Fembed[2] = {1, 1 - GAMMA}, Ferror[2] = {0, 1}, Serror[2] = {1, 0}; 1759566063dSJacob Faibussowitsch PetscCall(TSGLEERegister(TSGLEE23, p, s, r, GAMMA, &A[0][0], &B[0][0], &U[0][0], &V[0][0], S, F, NULL, Fembed, Ferror, Serror, 0, NULL)); 1762302aa1bSDebojyoti Ghosh } 1772302aa1bSDebojyoti Ghosh { 178b1fbfd33SSatish Balay #undef GAMMA 179b1fbfd33SSatish Balay #define GAMMA 0.0 1802302aa1bSDebojyoti Ghosh /* y-y~ form */ 1819371c9d4SSatish Balay const PetscInt p = 2, s = 4, r = 2; 1829371c9d4SSatish Balay const PetscReal A[4][4] = 1839371c9d4SSatish Balay { 1849371c9d4SSatish Balay {0, 0, 0, 0}, 1859371c9d4SSatish Balay {0.75, 0, 0, 0}, 1869371c9d4SSatish Balay {0.25, 29.0 / 60.0, 0, 0}, 1879371c9d4SSatish Balay {-21.0 / 44.0, 145.0 / 44.0, -20.0 / 11.0, 0} 1889371c9d4SSatish Balay }, 1899371c9d4SSatish Balay B[2][4] = {{109.0 / 275.0, 58.0 / 75.0, -37.0 / 110.0, 1.0 / 6.0}, {3.0 / 11.0, 0, 75.0 / 88.0, -1.0 / 8.0}}, U[4][2] = {{0, 1}, {75.0 / 58.0, -17.0 / 58.0}, {0, 1}, {0, 1}}, V[2][2] = {{1, 0}, {0, 1}}, S[2] = {1, 1}, F[2] = {1, 0}, Fembed[2] = {0, 1}, Ferror[2] = {-1.0 / (1.0 - GAMMA), 1.0 / (1.0 - GAMMA)}, Serror[2] = {1.0 - GAMMA, 1.0}; 1909566063dSJacob Faibussowitsch PetscCall(TSGLEERegister(TSGLEE24, p, s, r, GAMMA, &A[0][0], &B[0][0], &U[0][0], &V[0][0], S, F, NULL, Fembed, Ferror, Serror, 0, NULL)); 1912302aa1bSDebojyoti Ghosh } 1922302aa1bSDebojyoti Ghosh { 193b1fbfd33SSatish Balay #undef GAMMA 194b1fbfd33SSatish Balay #define GAMMA 0.0 1952302aa1bSDebojyoti Ghosh /* y-y~ form */ 1969371c9d4SSatish Balay const PetscInt p = 2, s = 5, r = 2; 1979371c9d4SSatish Balay const PetscReal A[5][5] = 1989371c9d4SSatish Balay { 1999371c9d4SSatish Balay {0, 0, 0, 0, 0}, 2002302aa1bSDebojyoti Ghosh {-0.94079244066783383269, 0, 0, 0, 0}, 2012302aa1bSDebojyoti Ghosh {0.64228187778301907108, 0.10915356933958500042, 0, 0, 0}, 2022302aa1bSDebojyoti Ghosh {-0.51764297742287450812, 0.74414270351096040738, -0.71404164927824538121, 0, 0}, 2039371c9d4SSatish Balay {-0.44696561556825969206, -0.76768425657590196518, 0.20111608138142987881, 0.93828186737840469796, 0} 2049371c9d4SSatish Balay }, 2059371c9d4SSatish Balay B[2][5] = {{-0.029309178948150356153, -0.49671981884013874923, 0.34275801517650053274, 0.32941112623949194988, 0.85385985637229662276}, {0.78133219686062535272, 0.074238691892675897635, 0.57957363498384957966, -0.24638502829674959968, -0.18875949544040123033}}, U[5][2] = {{0.16911424754448327735, 0.83088575245551672265}, {0.53638465733199574340, 0.46361534266800425660}, {0.39901579167169582526, 0.60098420832830417474}, {0.87689005530618575480, 0.12310994469381424520}, {0.99056100455550913009, 0.0094389954444908699092}}, V[2][2] = {{1, 0}, {0, 1}}, S[2] = {1, 1}, F[2] = {1, 0}, Fembed[2] = {0, 1}, Ferror[2] = {-1.0 / (1.0 - GAMMA), 1.0 / (1.0 - GAMMA)}, Serror[2] = {1.0 - GAMMA, 1.0}; 2069566063dSJacob Faibussowitsch PetscCall(TSGLEERegister(TSGLEE25I, p, s, r, GAMMA, &A[0][0], &B[0][0], &U[0][0], &V[0][0], S, F, NULL, Fembed, Ferror, Serror, 0, NULL)); 2072302aa1bSDebojyoti Ghosh } 2082302aa1bSDebojyoti Ghosh { 209b1fbfd33SSatish Balay #undef GAMMA 210b1fbfd33SSatish Balay #define GAMMA 0.0 2112302aa1bSDebojyoti Ghosh /* y-y~ form */ 2129371c9d4SSatish Balay const PetscInt p = 3, s = 5, r = 2; 2139371c9d4SSatish Balay const PetscReal A[5][5] = 2149371c9d4SSatish Balay { 2159371c9d4SSatish Balay {0, 0, 0, 0, 0}, 2162302aa1bSDebojyoti Ghosh {-2169604947363702313.0 / 24313474998937147335.0, 0, 0, 0, 0}, 2172302aa1bSDebojyoti Ghosh {46526746497697123895.0 / 94116917485856474137.0, -10297879244026594958.0 / 49199457603717988219.0, 0, 0, 0}, 2182302aa1bSDebojyoti Ghosh {23364788935845982499.0 / 87425311444725389446.0, -79205144337496116638.0 / 148994349441340815519.0, 40051189859317443782.0 / 36487615018004984309.0, 0, 0}, 2199371c9d4SSatish Balay {42089522664062539205.0 / 124911313006412840286.0, -15074384760342762939.0 / 137927286865289746282.0, -62274678522253371016.0 / 125918573676298591413.0, 13755475729852471739.0 / 79257927066651693390.0, 0} 2209371c9d4SSatish Balay }, 2219371c9d4SSatish Balay B[2][5] = {{61546696837458703723.0 / 56982519523786160813.0, -55810892792806293355.0 / 206957624151308356511.0, 24061048952676379087.0 / 158739347956038723465.0, 3577972206874351339.0 / 7599733370677197135.0, -59449832954780563947.0 / 137360038685338563670.0}, {-9738262186984159168.0 / 99299082461487742983.0, -32797097931948613195.0 / 61521565616362163366.0, 42895514606418420631.0 / 71714201188501437336.0, 22608567633166065068.0 / 55371917805607957003.0, 94655809487476459565.0 / 151517167160302729021.0}}, U[5][2] = {{70820309139834661559.0 / 80863923579509469826.0, 10043614439674808267.0 / 80863923579509469826.0}, {161694774978034105510.0 / 106187653640211060371.0, -55507121337823045139.0 / 106187653640211060371.0}, {78486094644566264568.0 / 88171030896733822981.0, 9684936252167558413.0 / 88171030896733822981.0}, {65394922146334854435.0 / 84570853840405479554.0, 19175931694070625119.0 / 84570853840405479554.0}, {8607282770183754108.0 / 108658046436496925911.0, 100050763666313171803.0 / 108658046436496925911.0}}, V[2][2] = {{1, 0}, {0, 1}}, S[2] = {1, 1}, F[2] = {1, 0}, Fembed[2] = {0, 1}, Ferror[2] = {-1.0 / (1.0 - GAMMA), 1.0 / (1.0 - GAMMA)}, Serror[2] = {1.0 - GAMMA, 1.0}; 2229566063dSJacob Faibussowitsch PetscCall(TSGLEERegister(TSGLEE35, p, s, r, GAMMA, &A[0][0], &B[0][0], &U[0][0], &V[0][0], S, F, NULL, Fembed, Ferror, Serror, 0, NULL)); 2232302aa1bSDebojyoti Ghosh } 2242302aa1bSDebojyoti Ghosh { 225b1fbfd33SSatish Balay #undef GAMMA 226b1fbfd33SSatish Balay #define GAMMA 0.25 2272302aa1bSDebojyoti Ghosh /* y-eps form */ 2289371c9d4SSatish Balay const PetscInt p = 2, s = 6, r = 2; 2299371c9d4SSatish Balay const PetscReal A[6][6] = 2309371c9d4SSatish Balay { 2319371c9d4SSatish Balay {0, 0, 0, 0, 0, 0}, 2322302aa1bSDebojyoti Ghosh {1, 0, 0, 0, 0, 0}, 2332302aa1bSDebojyoti Ghosh {0, 0, 0, 0, 0, 0}, 2342302aa1bSDebojyoti Ghosh {0, 0, 0.5, 0, 0, 0}, 2352302aa1bSDebojyoti Ghosh {0, 0, 0.25, 0.25, 0, 0}, 2369371c9d4SSatish Balay {0, 0, 0.25, 0.25, 0.5, 0} 2379371c9d4SSatish Balay }, 2389371c9d4SSatish Balay B[2][6] = {{0.5, 0.5, 0, 0, 0, 0}, {-2.0 / 3.0, -2.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0}}, U[6][2] = {{1, 0}, {1, 0}, {1, 0.75}, {1, 0.75}, {1, 0.75}, {1, 0.75}}, V[2][2] = {{1, 0}, {0, 1}}, S[2] = {1, 0}, F[2] = {1, 0}, Fembed[2] = {1, 1 - GAMMA}, Ferror[2] = {0, 1}, Serror[2] = {1, 0}; 2399566063dSJacob Faibussowitsch PetscCall(TSGLEERegister(TSGLEEEXRK2A, p, s, r, GAMMA, &A[0][0], &B[0][0], &U[0][0], &V[0][0], S, F, NULL, Fembed, Ferror, Serror, 0, NULL)); 2402302aa1bSDebojyoti Ghosh } 2412302aa1bSDebojyoti Ghosh { 242b1fbfd33SSatish Balay #undef GAMMA 243b1fbfd33SSatish Balay #define GAMMA 0.0 2442302aa1bSDebojyoti Ghosh /* y-eps form */ 2459371c9d4SSatish Balay const PetscInt p = 3, s = 8, r = 2; 2469371c9d4SSatish Balay const PetscReal A[8][8] = 2479371c9d4SSatish Balay { 2489371c9d4SSatish Balay {0, 0, 0, 0, 0, 0, 0, 0}, 2492302aa1bSDebojyoti Ghosh {0.5, 0, 0, 0, 0, 0, 0, 0}, 2502302aa1bSDebojyoti Ghosh {-1, 2, 0, 0, 0, 0, 0, 0}, 2512302aa1bSDebojyoti Ghosh {1.0 / 6.0, 2.0 / 3.0, 1.0 / 6.0, 0, 0, 0, 0, 0}, 2522302aa1bSDebojyoti Ghosh {0, 0, 0, 0, 0, 0, 0, 0}, 2532302aa1bSDebojyoti Ghosh {-7.0 / 24.0, 1.0 / 3.0, 1.0 / 12.0, -1.0 / 8.0, 0.5, 0, 0, 0}, 2542302aa1bSDebojyoti Ghosh {7.0 / 6.0, -4.0 / 3.0, -1.0 / 3.0, 0.5, -1.0, 2.0, 0, 0}, 2559371c9d4SSatish Balay {0, 0, 0, 0, 1.0 / 6.0, 2.0 / 3.0, 1.0 / 6.0, 0} 2569371c9d4SSatish Balay }, 2579371c9d4SSatish Balay B[2][8] = {{1.0 / 6.0, 2.0 / 3.0, 1.0 / 6.0, 0, 0, 0, 0, 0}, {-1.0 / 6.0, -2.0 / 3.0, -1.0 / 6.0, 0, 1.0 / 6.0, 2.0 / 3.0, 1.0 / 6.0, 0}}, U[8][2] = {{1, 0}, {1, 0}, {1, 0}, {1, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}}, V[2][2] = {{1, 0}, {0, 1}}, S[2] = {1, 0}, F[2] = {1, 0}, Fembed[2] = {1, 1 - GAMMA}, Ferror[2] = {0, 1}, Serror[2] = {1, 0}; 2589566063dSJacob Faibussowitsch PetscCall(TSGLEERegister(TSGLEERK32G1, p, s, r, GAMMA, &A[0][0], &B[0][0], &U[0][0], &V[0][0], S, F, NULL, Fembed, Ferror, Serror, 0, NULL)); 2592302aa1bSDebojyoti Ghosh } 2602302aa1bSDebojyoti Ghosh { 261b1fbfd33SSatish Balay #undef GAMMA 262b1fbfd33SSatish Balay #define GAMMA 0.25 2632302aa1bSDebojyoti Ghosh /* y-eps form */ 2649371c9d4SSatish Balay const PetscInt p = 2, s = 9, r = 2; 2659371c9d4SSatish Balay const PetscReal A[9][9] = 2669371c9d4SSatish Balay { 2679371c9d4SSatish Balay {0, 0, 0, 0, 0, 0, 0, 0, 0}, 2682302aa1bSDebojyoti Ghosh {0.585786437626904966, 0, 0, 0, 0, 0, 0, 0, 0}, 2692302aa1bSDebojyoti Ghosh {0.149999999999999994, 0.849999999999999978, 0, 0, 0, 0, 0, 0, 0}, 2702302aa1bSDebojyoti Ghosh {0, 0, 0, 0, 0, 0, 0, 0, 0}, 2712302aa1bSDebojyoti Ghosh {0, 0, 0, 0.292893218813452483, 0, 0, 0, 0, 0}, 2722302aa1bSDebojyoti Ghosh {0, 0, 0, 0.0749999999999999972, 0.424999999999999989, 0, 0, 0, 0}, 2732302aa1bSDebojyoti Ghosh {0, 0, 0, 0.176776695296636893, 0.176776695296636893, 0.146446609406726241, 0, 0, 0}, 2742302aa1bSDebojyoti Ghosh {0, 0, 0, 0.176776695296636893, 0.176776695296636893, 0.146446609406726241, 0.292893218813452483, 0, 0}, 2759371c9d4SSatish Balay {0, 0, 0, 0.176776695296636893, 0.176776695296636893, 0.146446609406726241, 0.0749999999999999972, 0.424999999999999989, 0} 2769371c9d4SSatish Balay }, 2779371c9d4SSatish Balay B[2][9] = {{0.353553390593273786, 0.353553390593273786, 0.292893218813452483, 0, 0, 0, 0, 0, 0}, {-0.471404520791031678, -0.471404520791031678, -0.390524291751269959, 0.235702260395515839, 0.235702260395515839, 0.195262145875634979, 0.235702260395515839, 0.235702260395515839, 0.195262145875634979}}, U[9][2] = {{1, 0}, {1, 0}, {1, 0}, {1, 0.75}, {1, 0.75}, {1, 0.75}, {1, 0.75}, {1, 0.75}, {1, 0.75}}, V[2][2] = {{1, 0}, {0, 1}}, S[2] = {1, 0}, F[2] = {1, 0}, Fembed[2] = {1, 1 - GAMMA}, Ferror[2] = {0, 1}, Serror[2] = {1, 0}; 2789566063dSJacob Faibussowitsch PetscCall(TSGLEERegister(TSGLEERK285EX, p, s, r, GAMMA, &A[0][0], &B[0][0], &U[0][0], &V[0][0], S, F, NULL, Fembed, Ferror, Serror, 0, NULL)); 2792302aa1bSDebojyoti Ghosh } 2802302aa1bSDebojyoti Ghosh 2812302aa1bSDebojyoti Ghosh PetscFunctionReturn(0); 2822302aa1bSDebojyoti Ghosh } 2832302aa1bSDebojyoti Ghosh 2842302aa1bSDebojyoti Ghosh /*@C 2852302aa1bSDebojyoti Ghosh TSGLEERegisterDestroy - Frees the list of schemes that were registered by TSGLEERegister(). 2862302aa1bSDebojyoti Ghosh 2872302aa1bSDebojyoti Ghosh Not Collective 2882302aa1bSDebojyoti Ghosh 2892302aa1bSDebojyoti Ghosh Level: advanced 2902302aa1bSDebojyoti Ghosh 291db781477SPatrick Sanan .seealso: `TSGLEERegister()`, `TSGLEERegisterAll()` 2922302aa1bSDebojyoti Ghosh @*/ 293*d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGLEERegisterDestroy(void) 294*d71ae5a4SJacob Faibussowitsch { 2952302aa1bSDebojyoti Ghosh GLEETableauLink link; 2962302aa1bSDebojyoti Ghosh 2972302aa1bSDebojyoti Ghosh PetscFunctionBegin; 2982302aa1bSDebojyoti Ghosh while ((link = GLEETableauList)) { 2992302aa1bSDebojyoti Ghosh GLEETableau t = &link->tab; 3002302aa1bSDebojyoti Ghosh GLEETableauList = link->next; 3019566063dSJacob Faibussowitsch PetscCall(PetscFree5(t->A, t->B, t->U, t->V, t->c)); 302d0609cedSBarry Smith PetscCall(PetscFree2(t->S, t->F)); 303d0609cedSBarry Smith PetscCall(PetscFree(t->Fembed)); 304d0609cedSBarry Smith PetscCall(PetscFree(t->Ferror)); 305d0609cedSBarry Smith PetscCall(PetscFree(t->Serror)); 306d0609cedSBarry Smith PetscCall(PetscFree(t->binterp)); 307d0609cedSBarry Smith PetscCall(PetscFree(t->name)); 308d0609cedSBarry Smith PetscCall(PetscFree(link)); 3092302aa1bSDebojyoti Ghosh } 3102302aa1bSDebojyoti Ghosh TSGLEERegisterAllCalled = PETSC_FALSE; 3112302aa1bSDebojyoti Ghosh PetscFunctionReturn(0); 3122302aa1bSDebojyoti Ghosh } 3132302aa1bSDebojyoti Ghosh 3142302aa1bSDebojyoti Ghosh /*@C 3152302aa1bSDebojyoti Ghosh TSGLEEInitializePackage - This function initializes everything in the TSGLEE package. It is called 3168a690491SBarry Smith from TSInitializePackage(). 3172302aa1bSDebojyoti Ghosh 3182302aa1bSDebojyoti Ghosh Level: developer 3192302aa1bSDebojyoti Ghosh 320db781477SPatrick Sanan .seealso: `PetscInitialize()` 3212302aa1bSDebojyoti Ghosh @*/ 322*d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGLEEInitializePackage(void) 323*d71ae5a4SJacob Faibussowitsch { 3242302aa1bSDebojyoti Ghosh PetscFunctionBegin; 3252302aa1bSDebojyoti Ghosh if (TSGLEEPackageInitialized) PetscFunctionReturn(0); 3262302aa1bSDebojyoti Ghosh TSGLEEPackageInitialized = PETSC_TRUE; 3279566063dSJacob Faibussowitsch PetscCall(TSGLEERegisterAll()); 3289566063dSJacob Faibussowitsch PetscCall(PetscObjectComposedDataRegister(&explicit_stage_time_id)); 3299566063dSJacob Faibussowitsch PetscCall(PetscRegisterFinalize(TSGLEEFinalizePackage)); 3302302aa1bSDebojyoti Ghosh PetscFunctionReturn(0); 3312302aa1bSDebojyoti Ghosh } 3322302aa1bSDebojyoti Ghosh 3332302aa1bSDebojyoti Ghosh /*@C 3342302aa1bSDebojyoti Ghosh TSGLEEFinalizePackage - This function destroys everything in the TSGLEE package. It is 3352302aa1bSDebojyoti Ghosh called from PetscFinalize(). 3362302aa1bSDebojyoti Ghosh 3372302aa1bSDebojyoti Ghosh Level: developer 3382302aa1bSDebojyoti Ghosh 339db781477SPatrick Sanan .seealso: `PetscFinalize()` 3402302aa1bSDebojyoti Ghosh @*/ 341*d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGLEEFinalizePackage(void) 342*d71ae5a4SJacob Faibussowitsch { 3432302aa1bSDebojyoti Ghosh PetscFunctionBegin; 3442302aa1bSDebojyoti Ghosh TSGLEEPackageInitialized = PETSC_FALSE; 3459566063dSJacob Faibussowitsch PetscCall(TSGLEERegisterDestroy()); 3462302aa1bSDebojyoti Ghosh PetscFunctionReturn(0); 3472302aa1bSDebojyoti Ghosh } 3482302aa1bSDebojyoti Ghosh 3492302aa1bSDebojyoti Ghosh /*@C 3502302aa1bSDebojyoti Ghosh TSGLEERegister - register an GLEE scheme by providing the entries in the Butcher tableau 3512302aa1bSDebojyoti Ghosh 3522302aa1bSDebojyoti Ghosh Not Collective, but the same schemes should be registered on all processes on which they will be used 3532302aa1bSDebojyoti Ghosh 3542302aa1bSDebojyoti Ghosh Input Parameters: 3552302aa1bSDebojyoti Ghosh + name - identifier for method 3562302aa1bSDebojyoti Ghosh . order - order of method 3572302aa1bSDebojyoti Ghosh . s - number of stages 3582302aa1bSDebojyoti Ghosh . r - number of steps 3592302aa1bSDebojyoti Ghosh . gamma - LTE ratio 3602302aa1bSDebojyoti Ghosh . A - stage coefficients (dimension s*s, row-major) 3612302aa1bSDebojyoti Ghosh . B - step completion coefficients (dimension r*s, row-major) 3622302aa1bSDebojyoti Ghosh . U - method coefficients (dimension s*r, row-major) 3632302aa1bSDebojyoti Ghosh . V - method coefficients (dimension r*r, row-major) 3642302aa1bSDebojyoti Ghosh . S - starting coefficients 3652302aa1bSDebojyoti Ghosh . F - finishing coefficients 3662302aa1bSDebojyoti Ghosh . c - abscissa (dimension s; NULL to use row sums of A) 3672302aa1bSDebojyoti Ghosh . Fembed - step completion coefficients for embedded method 368fd96ebc2SDebojyoti Ghosh . Ferror - error computation coefficients 36957df6a1bSDebojyoti Ghosh . Serror - error initialization coefficients 3702302aa1bSDebojyoti Ghosh . pinterp - order of interpolation (0 if unavailable) 3712302aa1bSDebojyoti Ghosh - binterp - array of interpolation coefficients (NULL if unavailable) 3722302aa1bSDebojyoti Ghosh 3732302aa1bSDebojyoti Ghosh Notes: 3742302aa1bSDebojyoti Ghosh Several GLEE methods are provided, this function is only needed to create new methods. 3752302aa1bSDebojyoti Ghosh 3762302aa1bSDebojyoti Ghosh Level: advanced 3772302aa1bSDebojyoti Ghosh 378db781477SPatrick Sanan .seealso: `TSGLEE` 3792302aa1bSDebojyoti Ghosh @*/ 380*d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGLEERegister(TSGLEEType name, PetscInt order, PetscInt s, PetscInt r, PetscReal gamma, const PetscReal A[], const PetscReal B[], const PetscReal U[], const PetscReal V[], const PetscReal S[], const PetscReal F[], const PetscReal c[], const PetscReal Fembed[], const PetscReal Ferror[], const PetscReal Serror[], PetscInt pinterp, const PetscReal binterp[]) 381*d71ae5a4SJacob Faibussowitsch { 3822302aa1bSDebojyoti Ghosh GLEETableauLink link; 3832302aa1bSDebojyoti Ghosh GLEETableau t; 3842302aa1bSDebojyoti Ghosh PetscInt i, j; 3852302aa1bSDebojyoti Ghosh 3862302aa1bSDebojyoti Ghosh PetscFunctionBegin; 3879566063dSJacob Faibussowitsch PetscCall(TSGLEEInitializePackage()); 3889566063dSJacob Faibussowitsch PetscCall(PetscNew(&link)); 3892302aa1bSDebojyoti Ghosh t = &link->tab; 3909566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(name, &t->name)); 3912302aa1bSDebojyoti Ghosh t->order = order; 3922302aa1bSDebojyoti Ghosh t->s = s; 3932302aa1bSDebojyoti Ghosh t->r = r; 3942302aa1bSDebojyoti Ghosh t->gamma = gamma; 3959566063dSJacob Faibussowitsch PetscCall(PetscMalloc5(s * s, &t->A, r * r, &t->V, s, &t->c, r * s, &t->B, s * r, &t->U)); 3969566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(r, &t->S, r, &t->F)); 3979566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(t->A, A, s * s)); 3989566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(t->B, B, r * s)); 3999566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(t->U, U, s * r)); 4009566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(t->V, V, r * r)); 4019566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(t->S, S, r)); 4029566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(t->F, F, r)); 4032302aa1bSDebojyoti Ghosh if (c) { 4049566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(t->c, c, s)); 4052302aa1bSDebojyoti Ghosh } else { 4069371c9d4SSatish Balay for (i = 0; i < s; i++) 4079371c9d4SSatish Balay for (j = 0, t->c[i] = 0; j < s; j++) t->c[i] += A[i * s + j]; 4082302aa1bSDebojyoti Ghosh } 4099566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(r, &t->Fembed)); 4109566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(r, &t->Ferror)); 4119566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(r, &t->Serror)); 4129566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(t->Fembed, Fembed, r)); 4139566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(t->Ferror, Ferror, r)); 4149566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(t->Serror, Serror, r)); 4152302aa1bSDebojyoti Ghosh t->pinterp = pinterp; 4169566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(s * pinterp, &t->binterp)); 4179566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(t->binterp, binterp, s * pinterp)); 4182302aa1bSDebojyoti Ghosh 4192302aa1bSDebojyoti Ghosh link->next = GLEETableauList; 4202302aa1bSDebojyoti Ghosh GLEETableauList = link; 4212302aa1bSDebojyoti Ghosh PetscFunctionReturn(0); 4222302aa1bSDebojyoti Ghosh } 4232302aa1bSDebojyoti Ghosh 424*d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSEvaluateStep_GLEE(TS ts, PetscInt order, Vec X, PetscBool *done) 425*d71ae5a4SJacob Faibussowitsch { 4262302aa1bSDebojyoti Ghosh TS_GLEE *glee = (TS_GLEE *)ts->data; 4272302aa1bSDebojyoti Ghosh GLEETableau tab = glee->tableau; 4289371c9d4SSatish Balay PetscReal h, *B = tab->B, *V = tab->V, *F = tab->F, *Fembed = tab->Fembed; 4292302aa1bSDebojyoti Ghosh PetscInt s = tab->s, r = tab->r, i, j; 4302302aa1bSDebojyoti Ghosh Vec *Y = glee->Y, *YdotStage = glee->YdotStage; 431ec0e3ee2SEmil Constantinescu PetscScalar *ws = glee->swork, *wr = glee->rwork; 4322302aa1bSDebojyoti Ghosh 4332302aa1bSDebojyoti Ghosh PetscFunctionBegin; 4342302aa1bSDebojyoti Ghosh 4352302aa1bSDebojyoti Ghosh switch (glee->status) { 4362302aa1bSDebojyoti Ghosh case TS_STEP_INCOMPLETE: 437*d71ae5a4SJacob Faibussowitsch case TS_STEP_PENDING: 438*d71ae5a4SJacob Faibussowitsch h = ts->time_step; 439*d71ae5a4SJacob Faibussowitsch break; 440*d71ae5a4SJacob Faibussowitsch case TS_STEP_COMPLETE: 441*d71ae5a4SJacob Faibussowitsch h = ts->ptime - ts->ptime_prev; 442*d71ae5a4SJacob Faibussowitsch break; 443*d71ae5a4SJacob Faibussowitsch default: 444*d71ae5a4SJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)ts), PETSC_ERR_PLIB, "Invalid TSStepStatus"); 4452302aa1bSDebojyoti Ghosh } 4462302aa1bSDebojyoti Ghosh 4472302aa1bSDebojyoti Ghosh if (order == tab->order) { 4482302aa1bSDebojyoti Ghosh /* Note: Irrespective of whether status is TS_STEP_INCOMPLETE 449fd96ebc2SDebojyoti Ghosh or TS_STEP_COMPLETE, glee->X has the solution at the 4502302aa1bSDebojyoti Ghosh beginning of the time step. So no need to roll-back. 4512302aa1bSDebojyoti Ghosh */ 4522302aa1bSDebojyoti Ghosh if (glee->status == TS_STEP_INCOMPLETE) { 4532302aa1bSDebojyoti Ghosh for (i = 0; i < r; i++) { 4549566063dSJacob Faibussowitsch PetscCall(VecZeroEntries(Y[i])); 455ec0e3ee2SEmil Constantinescu for (j = 0; j < r; j++) wr[j] = V[i * r + j]; 4569566063dSJacob Faibussowitsch PetscCall(VecMAXPY(Y[i], r, wr, glee->X)); 457ec0e3ee2SEmil Constantinescu for (j = 0; j < s; j++) ws[j] = h * B[i * s + j]; 4589566063dSJacob Faibussowitsch PetscCall(VecMAXPY(Y[i], s, ws, YdotStage)); 4592302aa1bSDebojyoti Ghosh } 4609566063dSJacob Faibussowitsch PetscCall(VecZeroEntries(X)); 461ec0e3ee2SEmil Constantinescu for (j = 0; j < r; j++) wr[j] = F[j]; 4629566063dSJacob Faibussowitsch PetscCall(VecMAXPY(X, r, wr, Y)); 4639566063dSJacob Faibussowitsch } else PetscCall(VecCopy(ts->vec_sol, X)); 4642302aa1bSDebojyoti Ghosh PetscFunctionReturn(0); 4652302aa1bSDebojyoti Ghosh 4662302aa1bSDebojyoti Ghosh } else if (order == tab->order - 1) { 4672302aa1bSDebojyoti Ghosh /* Complete with the embedded method (Fembed) */ 4682302aa1bSDebojyoti Ghosh for (i = 0; i < r; i++) { 4699566063dSJacob Faibussowitsch PetscCall(VecZeroEntries(Y[i])); 470ec0e3ee2SEmil Constantinescu for (j = 0; j < r; j++) wr[j] = V[i * r + j]; 4719566063dSJacob Faibussowitsch PetscCall(VecMAXPY(Y[i], r, wr, glee->X)); 472ec0e3ee2SEmil Constantinescu for (j = 0; j < s; j++) ws[j] = h * B[i * s + j]; 4739566063dSJacob Faibussowitsch PetscCall(VecMAXPY(Y[i], s, ws, YdotStage)); 4742302aa1bSDebojyoti Ghosh } 4759566063dSJacob Faibussowitsch PetscCall(VecZeroEntries(X)); 476ec0e3ee2SEmil Constantinescu for (j = 0; j < r; j++) wr[j] = Fembed[j]; 4779566063dSJacob Faibussowitsch PetscCall(VecMAXPY(X, r, wr, Y)); 478fd96ebc2SDebojyoti Ghosh 4792302aa1bSDebojyoti Ghosh if (done) *done = PETSC_TRUE; 4802302aa1bSDebojyoti Ghosh PetscFunctionReturn(0); 4812302aa1bSDebojyoti Ghosh } 4822302aa1bSDebojyoti Ghosh if (done) *done = PETSC_FALSE; 48363a3b9bcSJacob Faibussowitsch else SETERRQ(PetscObjectComm((PetscObject)ts), PETSC_ERR_SUP, "GLEE '%s' of order %" PetscInt_FMT " cannot evaluate step at order %" PetscInt_FMT, tab->name, tab->order, order); 4842302aa1bSDebojyoti Ghosh PetscFunctionReturn(0); 4852302aa1bSDebojyoti Ghosh } 4862302aa1bSDebojyoti Ghosh 487*d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSStep_GLEE(TS ts) 488*d71ae5a4SJacob Faibussowitsch { 4892302aa1bSDebojyoti Ghosh TS_GLEE *glee = (TS_GLEE *)ts->data; 4902302aa1bSDebojyoti Ghosh GLEETableau tab = glee->tableau; 4912302aa1bSDebojyoti Ghosh const PetscInt s = tab->s, r = tab->r; 4929371c9d4SSatish Balay PetscReal *A = tab->A, *U = tab->U, *F = tab->F, *c = tab->c; 4939371c9d4SSatish Balay Vec *Y = glee->Y, *X = glee->X, *YStage = glee->YStage, *YdotStage = glee->YdotStage, W = glee->W; 4942302aa1bSDebojyoti Ghosh SNES snes; 495ec0e3ee2SEmil Constantinescu PetscScalar *ws = glee->swork, *wr = glee->rwork; 4962302aa1bSDebojyoti Ghosh TSAdapt adapt; 4972302aa1bSDebojyoti Ghosh PetscInt i, j, reject, next_scheme, its, lits; 4982302aa1bSDebojyoti Ghosh PetscReal next_time_step; 4992302aa1bSDebojyoti Ghosh PetscReal t; 5002302aa1bSDebojyoti Ghosh PetscBool accept; 5012302aa1bSDebojyoti Ghosh 5022302aa1bSDebojyoti Ghosh PetscFunctionBegin; 5039566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(citation, &cited)); 504642f3702SEmil Constantinescu 5059566063dSJacob Faibussowitsch for (i = 0; i < r; i++) PetscCall(VecCopy(Y[i], X[i])); 5062302aa1bSDebojyoti Ghosh 5079566063dSJacob Faibussowitsch PetscCall(TSGetSNES(ts, &snes)); 5082302aa1bSDebojyoti Ghosh next_time_step = ts->time_step; 5092302aa1bSDebojyoti Ghosh t = ts->ptime; 5102302aa1bSDebojyoti Ghosh accept = PETSC_TRUE; 5112302aa1bSDebojyoti Ghosh glee->status = TS_STEP_INCOMPLETE; 5122302aa1bSDebojyoti Ghosh 5132302aa1bSDebojyoti Ghosh for (reject = 0; reject < ts->max_reject && !ts->reason; reject++, ts->reject++) { 5142302aa1bSDebojyoti Ghosh PetscReal h = ts->time_step; 5159566063dSJacob Faibussowitsch PetscCall(TSPreStep(ts)); 5162302aa1bSDebojyoti Ghosh 5172302aa1bSDebojyoti Ghosh for (i = 0; i < s; i++) { 5182302aa1bSDebojyoti Ghosh glee->stage_time = t + h * c[i]; 5199566063dSJacob Faibussowitsch PetscCall(TSPreStage(ts, glee->stage_time)); 5202302aa1bSDebojyoti Ghosh 5212302aa1bSDebojyoti Ghosh if (A[i * s + i] == 0) { /* Explicit stage */ 5229566063dSJacob Faibussowitsch PetscCall(VecZeroEntries(YStage[i])); 523ec0e3ee2SEmil Constantinescu for (j = 0; j < r; j++) wr[j] = U[i * r + j]; 5249566063dSJacob Faibussowitsch PetscCall(VecMAXPY(YStage[i], r, wr, X)); 525ec0e3ee2SEmil Constantinescu for (j = 0; j < i; j++) ws[j] = h * A[i * s + j]; 5269566063dSJacob Faibussowitsch PetscCall(VecMAXPY(YStage[i], i, ws, YdotStage)); 5272302aa1bSDebojyoti Ghosh } else { /* Implicit stage */ 5282302aa1bSDebojyoti Ghosh glee->scoeff = 1.0 / A[i * s + i]; 5292302aa1bSDebojyoti Ghosh /* compute right-hand-side */ 5309566063dSJacob Faibussowitsch PetscCall(VecZeroEntries(W)); 531ec0e3ee2SEmil Constantinescu for (j = 0; j < r; j++) wr[j] = U[i * r + j]; 5329566063dSJacob Faibussowitsch PetscCall(VecMAXPY(W, r, wr, X)); 533ec0e3ee2SEmil Constantinescu for (j = 0; j < i; j++) ws[j] = h * A[i * s + j]; 5349566063dSJacob Faibussowitsch PetscCall(VecMAXPY(W, i, ws, YdotStage)); 5359566063dSJacob Faibussowitsch PetscCall(VecScale(W, glee->scoeff / h)); 5362302aa1bSDebojyoti Ghosh /* set initial guess */ 5379566063dSJacob Faibussowitsch PetscCall(VecCopy(i > 0 ? YStage[i - 1] : ts->vec_sol, YStage[i])); 5382302aa1bSDebojyoti Ghosh /* solve for this stage */ 5399566063dSJacob Faibussowitsch PetscCall(SNESSolve(snes, W, YStage[i])); 5409566063dSJacob Faibussowitsch PetscCall(SNESGetIterationNumber(snes, &its)); 5419566063dSJacob Faibussowitsch PetscCall(SNESGetLinearSolveIterations(snes, &lits)); 5429371c9d4SSatish Balay ts->snes_its += its; 5439371c9d4SSatish Balay ts->ksp_its += lits; 5442302aa1bSDebojyoti Ghosh } 5459566063dSJacob Faibussowitsch PetscCall(TSGetAdapt(ts, &adapt)); 5469566063dSJacob Faibussowitsch PetscCall(TSAdaptCheckStage(adapt, ts, glee->stage_time, YStage[i], &accept)); 5472302aa1bSDebojyoti Ghosh if (!accept) goto reject_step; 5489566063dSJacob Faibussowitsch PetscCall(TSPostStage(ts, glee->stage_time, i, YStage)); 5499566063dSJacob Faibussowitsch PetscCall(TSComputeRHSFunction(ts, t + h * c[i], YStage[i], YdotStage[i])); 5502302aa1bSDebojyoti Ghosh } 5519566063dSJacob Faibussowitsch PetscCall(TSEvaluateStep(ts, tab->order, ts->vec_sol, NULL)); 5522302aa1bSDebojyoti Ghosh glee->status = TS_STEP_PENDING; 5532302aa1bSDebojyoti Ghosh 5542302aa1bSDebojyoti Ghosh /* Register only the current method as a candidate because we're not supporting multiple candidates yet. */ 5559566063dSJacob Faibussowitsch PetscCall(TSGetAdapt(ts, &adapt)); 5569566063dSJacob Faibussowitsch PetscCall(TSAdaptCandidatesClear(adapt)); 5579566063dSJacob Faibussowitsch PetscCall(TSAdaptCandidateAdd(adapt, tab->name, tab->order, 1, tab->ccfl, (PetscReal)tab->s, PETSC_TRUE)); 5589566063dSJacob Faibussowitsch PetscCall(TSAdaptChoose(adapt, ts, ts->time_step, &next_scheme, &next_time_step, &accept)); 5592302aa1bSDebojyoti Ghosh if (accept) { 5602302aa1bSDebojyoti Ghosh /* ignore next_scheme for now */ 5612302aa1bSDebojyoti Ghosh ts->ptime += ts->time_step; 5622302aa1bSDebojyoti Ghosh ts->time_step = next_time_step; 5632302aa1bSDebojyoti Ghosh glee->status = TS_STEP_COMPLETE; 5640a01e1b2SEmil Constantinescu /* compute and store the global error */ 5650a01e1b2SEmil Constantinescu /* Note: this is not needed if TSAdaptGLEE is not used */ 5669566063dSJacob Faibussowitsch PetscCall(TSGetTimeError(ts, 0, &(glee->yGErr))); 5679566063dSJacob Faibussowitsch PetscCall(PetscObjectComposedDataSetReal((PetscObject)ts->vec_sol, explicit_stage_time_id, ts->ptime)); 5682302aa1bSDebojyoti Ghosh break; 5692302aa1bSDebojyoti Ghosh } else { /* Roll back the current step */ 570ec0e3ee2SEmil Constantinescu for (j = 0; j < r; j++) wr[j] = F[j]; 5719566063dSJacob Faibussowitsch PetscCall(VecMAXPY(ts->vec_sol, r, wr, X)); 5722302aa1bSDebojyoti Ghosh ts->time_step = next_time_step; 5732302aa1bSDebojyoti Ghosh glee->status = TS_STEP_INCOMPLETE; 5742302aa1bSDebojyoti Ghosh } 5759371c9d4SSatish Balay reject_step: 5769371c9d4SSatish Balay continue; 5772302aa1bSDebojyoti Ghosh } 5782302aa1bSDebojyoti Ghosh if (glee->status != TS_STEP_COMPLETE && !ts->reason) ts->reason = TS_DIVERGED_STEP_REJECTED; 5792302aa1bSDebojyoti Ghosh PetscFunctionReturn(0); 5802302aa1bSDebojyoti Ghosh } 5812302aa1bSDebojyoti Ghosh 582*d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSInterpolate_GLEE(TS ts, PetscReal itime, Vec X) 583*d71ae5a4SJacob Faibussowitsch { 5842302aa1bSDebojyoti Ghosh TS_GLEE *glee = (TS_GLEE *)ts->data; 5852302aa1bSDebojyoti Ghosh PetscInt s = glee->tableau->s, pinterp = glee->tableau->pinterp, i, j; 5862302aa1bSDebojyoti Ghosh PetscReal h, tt, t; 5872302aa1bSDebojyoti Ghosh PetscScalar *b; 5882302aa1bSDebojyoti Ghosh const PetscReal *B = glee->tableau->binterp; 5892302aa1bSDebojyoti Ghosh 5902302aa1bSDebojyoti Ghosh PetscFunctionBegin; 5913c633725SBarry Smith PetscCheck(B, PetscObjectComm((PetscObject)ts), PETSC_ERR_SUP, "TSGLEE %s does not have an interpolation formula", glee->tableau->name); 5922302aa1bSDebojyoti Ghosh switch (glee->status) { 5932302aa1bSDebojyoti Ghosh case TS_STEP_INCOMPLETE: 5942302aa1bSDebojyoti Ghosh case TS_STEP_PENDING: 5952302aa1bSDebojyoti Ghosh h = ts->time_step; 5962302aa1bSDebojyoti Ghosh t = (itime - ts->ptime) / h; 5972302aa1bSDebojyoti Ghosh break; 5982302aa1bSDebojyoti Ghosh case TS_STEP_COMPLETE: 599ed450d42SEmil Constantinescu h = ts->ptime - ts->ptime_prev; 6002302aa1bSDebojyoti Ghosh t = (itime - ts->ptime) / h + 1; /* In the interval [0,1] */ 6012302aa1bSDebojyoti Ghosh break; 602*d71ae5a4SJacob Faibussowitsch default: 603*d71ae5a4SJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)ts), PETSC_ERR_PLIB, "Invalid TSStepStatus"); 6042302aa1bSDebojyoti Ghosh } 6059566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(s, &b)); 6062302aa1bSDebojyoti Ghosh for (i = 0; i < s; i++) b[i] = 0; 6072302aa1bSDebojyoti Ghosh for (j = 0, tt = t; j < pinterp; j++, tt *= t) { 608ad540459SPierre Jolivet for (i = 0; i < s; i++) b[i] += h * B[i * pinterp + j] * tt; 6092302aa1bSDebojyoti Ghosh } 6109566063dSJacob Faibussowitsch PetscCall(VecCopy(glee->YStage[0], X)); 6119566063dSJacob Faibussowitsch PetscCall(VecMAXPY(X, s, b, glee->YdotStage)); 6129566063dSJacob Faibussowitsch PetscCall(PetscFree(b)); 6132302aa1bSDebojyoti Ghosh PetscFunctionReturn(0); 6142302aa1bSDebojyoti Ghosh } 6152302aa1bSDebojyoti Ghosh 6162302aa1bSDebojyoti Ghosh /*------------------------------------------------------------*/ 617*d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSReset_GLEE(TS ts) 618*d71ae5a4SJacob Faibussowitsch { 6192302aa1bSDebojyoti Ghosh TS_GLEE *glee = (TS_GLEE *)ts->data; 6202302aa1bSDebojyoti Ghosh PetscInt s, r; 6212302aa1bSDebojyoti Ghosh 6222302aa1bSDebojyoti Ghosh PetscFunctionBegin; 6232302aa1bSDebojyoti Ghosh if (!glee->tableau) PetscFunctionReturn(0); 6242302aa1bSDebojyoti Ghosh s = glee->tableau->s; 6252302aa1bSDebojyoti Ghosh r = glee->tableau->r; 6269566063dSJacob Faibussowitsch PetscCall(VecDestroyVecs(r, &glee->Y)); 6279566063dSJacob Faibussowitsch PetscCall(VecDestroyVecs(r, &glee->X)); 6289566063dSJacob Faibussowitsch PetscCall(VecDestroyVecs(s, &glee->YStage)); 6299566063dSJacob Faibussowitsch PetscCall(VecDestroyVecs(s, &glee->YdotStage)); 6309566063dSJacob Faibussowitsch PetscCall(VecDestroy(&glee->Ydot)); 6319566063dSJacob Faibussowitsch PetscCall(VecDestroy(&glee->yGErr)); 6329566063dSJacob Faibussowitsch PetscCall(VecDestroy(&glee->W)); 6339566063dSJacob Faibussowitsch PetscCall(PetscFree2(glee->swork, glee->rwork)); 6342302aa1bSDebojyoti Ghosh PetscFunctionReturn(0); 6352302aa1bSDebojyoti Ghosh } 6362302aa1bSDebojyoti Ghosh 637*d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSGLEEGetVecs(TS ts, DM dm, Vec *Ydot) 638*d71ae5a4SJacob Faibussowitsch { 6392302aa1bSDebojyoti Ghosh TS_GLEE *glee = (TS_GLEE *)ts->data; 6402302aa1bSDebojyoti Ghosh 6412302aa1bSDebojyoti Ghosh PetscFunctionBegin; 6422302aa1bSDebojyoti Ghosh if (Ydot) { 6432302aa1bSDebojyoti Ghosh if (dm && dm != ts->dm) { 6449566063dSJacob Faibussowitsch PetscCall(DMGetNamedGlobalVector(dm, "TSGLEE_Ydot", Ydot)); 6452302aa1bSDebojyoti Ghosh } else *Ydot = glee->Ydot; 6462302aa1bSDebojyoti Ghosh } 6472302aa1bSDebojyoti Ghosh PetscFunctionReturn(0); 6482302aa1bSDebojyoti Ghosh } 6492302aa1bSDebojyoti Ghosh 650*d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSGLEERestoreVecs(TS ts, DM dm, Vec *Ydot) 651*d71ae5a4SJacob Faibussowitsch { 6522302aa1bSDebojyoti Ghosh PetscFunctionBegin; 6532302aa1bSDebojyoti Ghosh if (Ydot) { 65448a46eb9SPierre Jolivet if (dm && dm != ts->dm) PetscCall(DMRestoreNamedGlobalVector(dm, "TSGLEE_Ydot", Ydot)); 6552302aa1bSDebojyoti Ghosh } 6562302aa1bSDebojyoti Ghosh PetscFunctionReturn(0); 6572302aa1bSDebojyoti Ghosh } 6582302aa1bSDebojyoti Ghosh 6592302aa1bSDebojyoti Ghosh /* 6602302aa1bSDebojyoti Ghosh This defines the nonlinear equation that is to be solved with SNES 6612302aa1bSDebojyoti Ghosh */ 662*d71ae5a4SJacob Faibussowitsch static PetscErrorCode SNESTSFormFunction_GLEE(SNES snes, Vec X, Vec F, TS ts) 663*d71ae5a4SJacob Faibussowitsch { 6642302aa1bSDebojyoti Ghosh TS_GLEE *glee = (TS_GLEE *)ts->data; 6652302aa1bSDebojyoti Ghosh DM dm, dmsave; 6662302aa1bSDebojyoti Ghosh Vec Ydot; 6672302aa1bSDebojyoti Ghosh PetscReal shift = glee->scoeff / ts->time_step; 6682302aa1bSDebojyoti Ghosh 6692302aa1bSDebojyoti Ghosh PetscFunctionBegin; 6709566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 6719566063dSJacob Faibussowitsch PetscCall(TSGLEEGetVecs(ts, dm, &Ydot)); 6722302aa1bSDebojyoti Ghosh /* Set Ydot = shift*X */ 6739566063dSJacob Faibussowitsch PetscCall(VecCopy(X, Ydot)); 6749566063dSJacob Faibussowitsch PetscCall(VecScale(Ydot, shift)); 6752302aa1bSDebojyoti Ghosh dmsave = ts->dm; 6762302aa1bSDebojyoti Ghosh ts->dm = dm; 6772302aa1bSDebojyoti Ghosh 6789566063dSJacob Faibussowitsch PetscCall(TSComputeIFunction(ts, glee->stage_time, X, Ydot, F, PETSC_FALSE)); 6792302aa1bSDebojyoti Ghosh 6802302aa1bSDebojyoti Ghosh ts->dm = dmsave; 6819566063dSJacob Faibussowitsch PetscCall(TSGLEERestoreVecs(ts, dm, &Ydot)); 6822302aa1bSDebojyoti Ghosh PetscFunctionReturn(0); 6832302aa1bSDebojyoti Ghosh } 6842302aa1bSDebojyoti Ghosh 685*d71ae5a4SJacob Faibussowitsch static PetscErrorCode SNESTSFormJacobian_GLEE(SNES snes, Vec X, Mat A, Mat B, TS ts) 686*d71ae5a4SJacob Faibussowitsch { 6872302aa1bSDebojyoti Ghosh TS_GLEE *glee = (TS_GLEE *)ts->data; 6882302aa1bSDebojyoti Ghosh DM dm, dmsave; 6892302aa1bSDebojyoti Ghosh Vec Ydot; 6902302aa1bSDebojyoti Ghosh PetscReal shift = glee->scoeff / ts->time_step; 6912302aa1bSDebojyoti Ghosh 6922302aa1bSDebojyoti Ghosh PetscFunctionBegin; 6939566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 6949566063dSJacob Faibussowitsch PetscCall(TSGLEEGetVecs(ts, dm, &Ydot)); 6952302aa1bSDebojyoti Ghosh /* glee->Ydot has already been computed in SNESTSFormFunction_GLEE (SNES guarantees this) */ 6962302aa1bSDebojyoti Ghosh dmsave = ts->dm; 6972302aa1bSDebojyoti Ghosh ts->dm = dm; 6982302aa1bSDebojyoti Ghosh 6999566063dSJacob Faibussowitsch PetscCall(TSComputeIJacobian(ts, glee->stage_time, X, Ydot, shift, A, B, PETSC_FALSE)); 7002302aa1bSDebojyoti Ghosh 7012302aa1bSDebojyoti Ghosh ts->dm = dmsave; 7029566063dSJacob Faibussowitsch PetscCall(TSGLEERestoreVecs(ts, dm, &Ydot)); 7032302aa1bSDebojyoti Ghosh PetscFunctionReturn(0); 7042302aa1bSDebojyoti Ghosh } 7052302aa1bSDebojyoti Ghosh 706*d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMCoarsenHook_TSGLEE(DM fine, DM coarse, void *ctx) 707*d71ae5a4SJacob Faibussowitsch { 7082302aa1bSDebojyoti Ghosh PetscFunctionBegin; 7092302aa1bSDebojyoti Ghosh PetscFunctionReturn(0); 7102302aa1bSDebojyoti Ghosh } 7112302aa1bSDebojyoti Ghosh 712*d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMRestrictHook_TSGLEE(DM fine, Mat restrct, Vec rscale, Mat inject, DM coarse, void *ctx) 713*d71ae5a4SJacob Faibussowitsch { 7142302aa1bSDebojyoti Ghosh PetscFunctionBegin; 7152302aa1bSDebojyoti Ghosh PetscFunctionReturn(0); 7162302aa1bSDebojyoti Ghosh } 7172302aa1bSDebojyoti Ghosh 718*d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMSubDomainHook_TSGLEE(DM dm, DM subdm, void *ctx) 719*d71ae5a4SJacob Faibussowitsch { 7202302aa1bSDebojyoti Ghosh PetscFunctionBegin; 7212302aa1bSDebojyoti Ghosh PetscFunctionReturn(0); 7222302aa1bSDebojyoti Ghosh } 7232302aa1bSDebojyoti Ghosh 724*d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMSubDomainRestrictHook_TSGLEE(DM dm, VecScatter gscat, VecScatter lscat, DM subdm, void *ctx) 725*d71ae5a4SJacob Faibussowitsch { 7262302aa1bSDebojyoti Ghosh PetscFunctionBegin; 7272302aa1bSDebojyoti Ghosh PetscFunctionReturn(0); 7282302aa1bSDebojyoti Ghosh } 7292302aa1bSDebojyoti Ghosh 730*d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSSetUp_GLEE(TS ts) 731*d71ae5a4SJacob Faibussowitsch { 7322302aa1bSDebojyoti Ghosh TS_GLEE *glee = (TS_GLEE *)ts->data; 7332302aa1bSDebojyoti Ghosh GLEETableau tab; 7342302aa1bSDebojyoti Ghosh PetscInt s, r; 7352302aa1bSDebojyoti Ghosh DM dm; 7362302aa1bSDebojyoti Ghosh 7372302aa1bSDebojyoti Ghosh PetscFunctionBegin; 73848a46eb9SPierre Jolivet if (!glee->tableau) PetscCall(TSGLEESetType(ts, TSGLEEDefaultType)); 7392302aa1bSDebojyoti Ghosh tab = glee->tableau; 7402302aa1bSDebojyoti Ghosh s = tab->s; 7412302aa1bSDebojyoti Ghosh r = tab->r; 7429566063dSJacob Faibussowitsch PetscCall(VecDuplicateVecs(ts->vec_sol, r, &glee->Y)); 7439566063dSJacob Faibussowitsch PetscCall(VecDuplicateVecs(ts->vec_sol, r, &glee->X)); 7449566063dSJacob Faibussowitsch PetscCall(VecDuplicateVecs(ts->vec_sol, s, &glee->YStage)); 7459566063dSJacob Faibussowitsch PetscCall(VecDuplicateVecs(ts->vec_sol, s, &glee->YdotStage)); 7469566063dSJacob Faibussowitsch PetscCall(VecDuplicate(ts->vec_sol, &glee->Ydot)); 7479566063dSJacob Faibussowitsch PetscCall(VecDuplicate(ts->vec_sol, &glee->yGErr)); 7489566063dSJacob Faibussowitsch PetscCall(VecZeroEntries(glee->yGErr)); 7499566063dSJacob Faibussowitsch PetscCall(VecDuplicate(ts->vec_sol, &glee->W)); 7509566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(s, &glee->swork, r, &glee->rwork)); 7519566063dSJacob Faibussowitsch PetscCall(TSGetDM(ts, &dm)); 7529566063dSJacob Faibussowitsch PetscCall(DMCoarsenHookAdd(dm, DMCoarsenHook_TSGLEE, DMRestrictHook_TSGLEE, ts)); 7539566063dSJacob Faibussowitsch PetscCall(DMSubDomainHookAdd(dm, DMSubDomainHook_TSGLEE, DMSubDomainRestrictHook_TSGLEE, ts)); 7542302aa1bSDebojyoti Ghosh PetscFunctionReturn(0); 7552302aa1bSDebojyoti Ghosh } 7562302aa1bSDebojyoti Ghosh 757*d71ae5a4SJacob Faibussowitsch PetscErrorCode TSStartingMethod_GLEE(TS ts) 758*d71ae5a4SJacob Faibussowitsch { 7592302aa1bSDebojyoti Ghosh TS_GLEE *glee = (TS_GLEE *)ts->data; 7606e2e232bSDebojyoti Ghosh GLEETableau tab = glee->tableau; 7616e2e232bSDebojyoti Ghosh PetscInt r = tab->r, i; 7626e2e232bSDebojyoti Ghosh PetscReal *S = tab->S; 7632302aa1bSDebojyoti Ghosh 7642302aa1bSDebojyoti Ghosh PetscFunctionBegin; 7652302aa1bSDebojyoti Ghosh for (i = 0; i < r; i++) { 7669566063dSJacob Faibussowitsch PetscCall(VecZeroEntries(glee->Y[i])); 7679566063dSJacob Faibussowitsch PetscCall(VecAXPY(glee->Y[i], S[i], ts->vec_sol)); 7682302aa1bSDebojyoti Ghosh } 7692302aa1bSDebojyoti Ghosh 7702302aa1bSDebojyoti Ghosh PetscFunctionReturn(0); 7712302aa1bSDebojyoti Ghosh } 7722302aa1bSDebojyoti Ghosh 7732302aa1bSDebojyoti Ghosh /*------------------------------------------------------------*/ 7742302aa1bSDebojyoti Ghosh 775*d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSSetFromOptions_GLEE(TS ts, PetscOptionItems *PetscOptionsObject) 776*d71ae5a4SJacob Faibussowitsch { 7772302aa1bSDebojyoti Ghosh char gleetype[256]; 7782302aa1bSDebojyoti Ghosh 7792302aa1bSDebojyoti Ghosh PetscFunctionBegin; 780d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "GLEE ODE solver options"); 7812302aa1bSDebojyoti Ghosh { 7822302aa1bSDebojyoti Ghosh GLEETableauLink link; 7832302aa1bSDebojyoti Ghosh PetscInt count, choice; 7842302aa1bSDebojyoti Ghosh PetscBool flg; 7852302aa1bSDebojyoti Ghosh const char **namelist; 7862302aa1bSDebojyoti Ghosh 7879566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(gleetype, TSGLEEDefaultType, sizeof(gleetype))); 7889371c9d4SSatish Balay for (link = GLEETableauList, count = 0; link; link = link->next, count++) 7899371c9d4SSatish Balay ; 7909566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(count, (char ***)&namelist)); 7912302aa1bSDebojyoti Ghosh for (link = GLEETableauList, count = 0; link; link = link->next, count++) namelist[count] = link->tab.name; 7929566063dSJacob Faibussowitsch PetscCall(PetscOptionsEList("-ts_glee_type", "Family of GLEE method", "TSGLEESetType", (const char *const *)namelist, count, gleetype, &choice, &flg)); 7939566063dSJacob Faibussowitsch PetscCall(TSGLEESetType(ts, flg ? namelist[choice] : gleetype)); 7949566063dSJacob Faibussowitsch PetscCall(PetscFree(namelist)); 7952302aa1bSDebojyoti Ghosh } 796d0609cedSBarry Smith PetscOptionsHeadEnd(); 7972302aa1bSDebojyoti Ghosh PetscFunctionReturn(0); 7982302aa1bSDebojyoti Ghosh } 7992302aa1bSDebojyoti Ghosh 800*d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSView_GLEE(TS ts, PetscViewer viewer) 801*d71ae5a4SJacob Faibussowitsch { 8022302aa1bSDebojyoti Ghosh TS_GLEE *glee = (TS_GLEE *)ts->data; 8032302aa1bSDebojyoti Ghosh GLEETableau tab = glee->tableau; 8042302aa1bSDebojyoti Ghosh PetscBool iascii; 8052302aa1bSDebojyoti Ghosh 8062302aa1bSDebojyoti Ghosh PetscFunctionBegin; 8079566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 8082302aa1bSDebojyoti Ghosh if (iascii) { 8092302aa1bSDebojyoti Ghosh TSGLEEType gleetype; 8102302aa1bSDebojyoti Ghosh char buf[512]; 8119566063dSJacob Faibussowitsch PetscCall(TSGLEEGetType(ts, &gleetype)); 8129566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " GLEE type %s\n", gleetype)); 8139566063dSJacob Faibussowitsch PetscCall(PetscFormatRealArray(buf, sizeof(buf), "% 8.6f", tab->s, tab->c)); 8149566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Abscissa c = %s\n", buf)); 8152302aa1bSDebojyoti Ghosh /* Note: print out r as well */ 8162302aa1bSDebojyoti Ghosh } 8172302aa1bSDebojyoti Ghosh PetscFunctionReturn(0); 8182302aa1bSDebojyoti Ghosh } 8192302aa1bSDebojyoti Ghosh 820*d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSLoad_GLEE(TS ts, PetscViewer viewer) 821*d71ae5a4SJacob Faibussowitsch { 8222302aa1bSDebojyoti Ghosh SNES snes; 8232302aa1bSDebojyoti Ghosh TSAdapt tsadapt; 8242302aa1bSDebojyoti Ghosh 8252302aa1bSDebojyoti Ghosh PetscFunctionBegin; 8269566063dSJacob Faibussowitsch PetscCall(TSGetAdapt(ts, &tsadapt)); 8279566063dSJacob Faibussowitsch PetscCall(TSAdaptLoad(tsadapt, viewer)); 8289566063dSJacob Faibussowitsch PetscCall(TSGetSNES(ts, &snes)); 8299566063dSJacob Faibussowitsch PetscCall(SNESLoad(snes, viewer)); 8302302aa1bSDebojyoti Ghosh /* function and Jacobian context for SNES when used with TS is always ts object */ 8319566063dSJacob Faibussowitsch PetscCall(SNESSetFunction(snes, NULL, NULL, ts)); 8329566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, NULL, NULL, NULL, ts)); 8332302aa1bSDebojyoti Ghosh PetscFunctionReturn(0); 8342302aa1bSDebojyoti Ghosh } 8352302aa1bSDebojyoti Ghosh 8362302aa1bSDebojyoti Ghosh /*@C 8372302aa1bSDebojyoti Ghosh TSGLEESetType - Set the type of GLEE scheme 8382302aa1bSDebojyoti Ghosh 8392302aa1bSDebojyoti Ghosh Logically collective 8402302aa1bSDebojyoti Ghosh 841d8d19677SJose E. Roman Input Parameters: 8422302aa1bSDebojyoti Ghosh + ts - timestepping context 8432302aa1bSDebojyoti Ghosh - gleetype - type of GLEE-scheme 8442302aa1bSDebojyoti Ghosh 8452302aa1bSDebojyoti Ghosh Level: intermediate 8462302aa1bSDebojyoti Ghosh 847db781477SPatrick Sanan .seealso: `TSGLEEGetType()`, `TSGLEE` 8482302aa1bSDebojyoti Ghosh @*/ 849*d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGLEESetType(TS ts, TSGLEEType gleetype) 850*d71ae5a4SJacob Faibussowitsch { 8512302aa1bSDebojyoti Ghosh PetscFunctionBegin; 8522302aa1bSDebojyoti Ghosh PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 853b92453a8SLisandro Dalcin PetscValidCharPointer(gleetype, 2); 854cac4c232SBarry Smith PetscTryMethod(ts, "TSGLEESetType_C", (TS, TSGLEEType), (ts, gleetype)); 8552302aa1bSDebojyoti Ghosh PetscFunctionReturn(0); 8562302aa1bSDebojyoti Ghosh } 8572302aa1bSDebojyoti Ghosh 8582302aa1bSDebojyoti Ghosh /*@C 8592302aa1bSDebojyoti Ghosh TSGLEEGetType - Get the type of GLEE scheme 8602302aa1bSDebojyoti Ghosh 8612302aa1bSDebojyoti Ghosh Logically collective 8622302aa1bSDebojyoti Ghosh 8632302aa1bSDebojyoti Ghosh Input Parameter: 8642302aa1bSDebojyoti Ghosh . ts - timestepping context 8652302aa1bSDebojyoti Ghosh 8662302aa1bSDebojyoti Ghosh Output Parameter: 8672302aa1bSDebojyoti Ghosh . gleetype - type of GLEE-scheme 8682302aa1bSDebojyoti Ghosh 8692302aa1bSDebojyoti Ghosh Level: intermediate 8702302aa1bSDebojyoti Ghosh 871db781477SPatrick Sanan .seealso: `TSGLEESetType()` 8722302aa1bSDebojyoti Ghosh @*/ 873*d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGLEEGetType(TS ts, TSGLEEType *gleetype) 874*d71ae5a4SJacob Faibussowitsch { 8752302aa1bSDebojyoti Ghosh PetscFunctionBegin; 8762302aa1bSDebojyoti Ghosh PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 877cac4c232SBarry Smith PetscUseMethod(ts, "TSGLEEGetType_C", (TS, TSGLEEType *), (ts, gleetype)); 8782302aa1bSDebojyoti Ghosh PetscFunctionReturn(0); 8792302aa1bSDebojyoti Ghosh } 8802302aa1bSDebojyoti Ghosh 881*d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGLEEGetType_GLEE(TS ts, TSGLEEType *gleetype) 882*d71ae5a4SJacob Faibussowitsch { 8832302aa1bSDebojyoti Ghosh TS_GLEE *glee = (TS_GLEE *)ts->data; 8842302aa1bSDebojyoti Ghosh 8852302aa1bSDebojyoti Ghosh PetscFunctionBegin; 88648a46eb9SPierre Jolivet if (!glee->tableau) PetscCall(TSGLEESetType(ts, TSGLEEDefaultType)); 8872302aa1bSDebojyoti Ghosh *gleetype = glee->tableau->name; 8882302aa1bSDebojyoti Ghosh PetscFunctionReturn(0); 8892302aa1bSDebojyoti Ghosh } 890*d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGLEESetType_GLEE(TS ts, TSGLEEType gleetype) 891*d71ae5a4SJacob Faibussowitsch { 8922302aa1bSDebojyoti Ghosh TS_GLEE *glee = (TS_GLEE *)ts->data; 8932302aa1bSDebojyoti Ghosh PetscBool match; 8942302aa1bSDebojyoti Ghosh GLEETableauLink link; 8952302aa1bSDebojyoti Ghosh 8962302aa1bSDebojyoti Ghosh PetscFunctionBegin; 8972302aa1bSDebojyoti Ghosh if (glee->tableau) { 8989566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(glee->tableau->name, gleetype, &match)); 8992302aa1bSDebojyoti Ghosh if (match) PetscFunctionReturn(0); 9002302aa1bSDebojyoti Ghosh } 9012302aa1bSDebojyoti Ghosh for (link = GLEETableauList; link; link = link->next) { 9029566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(link->tab.name, gleetype, &match)); 9032302aa1bSDebojyoti Ghosh if (match) { 9049566063dSJacob Faibussowitsch PetscCall(TSReset_GLEE(ts)); 9052302aa1bSDebojyoti Ghosh glee->tableau = &link->tab; 9062302aa1bSDebojyoti Ghosh PetscFunctionReturn(0); 9072302aa1bSDebojyoti Ghosh } 9082302aa1bSDebojyoti Ghosh } 90998921bdaSJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_UNKNOWN_TYPE, "Could not find '%s'", gleetype); 9102302aa1bSDebojyoti Ghosh } 9112302aa1bSDebojyoti Ghosh 912*d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSGetStages_GLEE(TS ts, PetscInt *ns, Vec **Y) 913*d71ae5a4SJacob Faibussowitsch { 9142302aa1bSDebojyoti Ghosh TS_GLEE *glee = (TS_GLEE *)ts->data; 9152302aa1bSDebojyoti Ghosh 9162302aa1bSDebojyoti Ghosh PetscFunctionBegin; 9170429704eSStefano Zampini if (ns) *ns = glee->tableau->s; 918d5509560SEmil Constantinescu if (Y) *Y = glee->YStage; 9192302aa1bSDebojyoti Ghosh PetscFunctionReturn(0); 9202302aa1bSDebojyoti Ghosh } 9212302aa1bSDebojyoti Ghosh 922*d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetSolutionComponents_GLEE(TS ts, PetscInt *n, Vec *Y) 923*d71ae5a4SJacob Faibussowitsch { 9242302aa1bSDebojyoti Ghosh TS_GLEE *glee = (TS_GLEE *)ts->data; 9252302aa1bSDebojyoti Ghosh GLEETableau tab = glee->tableau; 9262302aa1bSDebojyoti Ghosh 9272302aa1bSDebojyoti Ghosh PetscFunctionBegin; 9284cdd57e5SDebojyoti Ghosh if (!Y) *n = tab->r; 9292302aa1bSDebojyoti Ghosh else { 9304cdd57e5SDebojyoti Ghosh if ((*n >= 0) && (*n < tab->r)) { 9319566063dSJacob Faibussowitsch PetscCall(VecCopy(glee->Y[*n], *Y)); 93263a3b9bcSJacob Faibussowitsch } else SETERRQ(PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_OUTOFRANGE, "Second argument (%" PetscInt_FMT ") out of range[0,%" PetscInt_FMT "].", *n, tab->r - 1); 9332302aa1bSDebojyoti Ghosh } 9342302aa1bSDebojyoti Ghosh PetscFunctionReturn(0); 9352302aa1bSDebojyoti Ghosh } 9362302aa1bSDebojyoti Ghosh 937*d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetAuxSolution_GLEE(TS ts, Vec *X) 938*d71ae5a4SJacob Faibussowitsch { 9394cdd57e5SDebojyoti Ghosh TS_GLEE *glee = (TS_GLEE *)ts->data; 9404cdd57e5SDebojyoti Ghosh GLEETableau tab = glee->tableau; 9414cdd57e5SDebojyoti Ghosh PetscReal *F = tab->Fembed; 9424cdd57e5SDebojyoti Ghosh PetscInt r = tab->r; 9434cdd57e5SDebojyoti Ghosh Vec *Y = glee->Y; 944ec0e3ee2SEmil Constantinescu PetscScalar *wr = glee->rwork; 945ec0e3ee2SEmil Constantinescu PetscInt i; 9464cdd57e5SDebojyoti Ghosh 9474cdd57e5SDebojyoti Ghosh PetscFunctionBegin; 9489566063dSJacob Faibussowitsch PetscCall(VecZeroEntries(*X)); 949ec0e3ee2SEmil Constantinescu for (i = 0; i < r; i++) wr[i] = F[i]; 9509566063dSJacob Faibussowitsch PetscCall(VecMAXPY((*X), r, wr, Y)); 9514cdd57e5SDebojyoti Ghosh PetscFunctionReturn(0); 9524cdd57e5SDebojyoti Ghosh } 9534cdd57e5SDebojyoti Ghosh 954*d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetTimeError_GLEE(TS ts, PetscInt n, Vec *X) 955*d71ae5a4SJacob Faibussowitsch { 9564cdd57e5SDebojyoti Ghosh TS_GLEE *glee = (TS_GLEE *)ts->data; 9574cdd57e5SDebojyoti Ghosh GLEETableau tab = glee->tableau; 9584cdd57e5SDebojyoti Ghosh PetscReal *F = tab->Ferror; 9594cdd57e5SDebojyoti Ghosh PetscInt r = tab->r; 9604cdd57e5SDebojyoti Ghosh Vec *Y = glee->Y; 961ec0e3ee2SEmil Constantinescu PetscScalar *wr = glee->rwork; 962ec0e3ee2SEmil Constantinescu PetscInt i; 9634cdd57e5SDebojyoti Ghosh 9644cdd57e5SDebojyoti Ghosh PetscFunctionBegin; 9659566063dSJacob Faibussowitsch PetscCall(VecZeroEntries(*X)); 966657c1e31SEmil Constantinescu if (n == 0) { 967ec0e3ee2SEmil Constantinescu for (i = 0; i < r; i++) wr[i] = F[i]; 9689566063dSJacob Faibussowitsch PetscCall(VecMAXPY((*X), r, wr, Y)); 9690a01e1b2SEmil Constantinescu } else if (n == -1) { 970657c1e31SEmil Constantinescu *X = glee->yGErr; 9710a01e1b2SEmil Constantinescu } 9724cdd57e5SDebojyoti Ghosh PetscFunctionReturn(0); 9734cdd57e5SDebojyoti Ghosh } 9744cdd57e5SDebojyoti Ghosh 975*d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetTimeError_GLEE(TS ts, Vec X) 976*d71ae5a4SJacob Faibussowitsch { 97757df6a1bSDebojyoti Ghosh TS_GLEE *glee = (TS_GLEE *)ts->data; 97857df6a1bSDebojyoti Ghosh GLEETableau tab = glee->tableau; 97957df6a1bSDebojyoti Ghosh PetscReal *S = tab->Serror; 98057df6a1bSDebojyoti Ghosh PetscInt r = tab->r, i; 98157df6a1bSDebojyoti Ghosh Vec *Y = glee->Y; 98257df6a1bSDebojyoti Ghosh 98357df6a1bSDebojyoti Ghosh PetscFunctionBegin; 98463a3b9bcSJacob Faibussowitsch PetscCheck(r == 2, PetscObjectComm((PetscObject)ts), PETSC_ERR_SUP, "TSSetTimeError_GLEE not supported for '%s' with r=%" PetscInt_FMT ".", tab->name, tab->r); 98557df6a1bSDebojyoti Ghosh for (i = 1; i < r; i++) { 9869566063dSJacob Faibussowitsch PetscCall(VecCopy(ts->vec_sol, Y[i])); 9879566063dSJacob Faibussowitsch PetscCall(VecAXPBY(Y[i], S[0], S[1], X)); 9889566063dSJacob Faibussowitsch PetscCall(VecCopy(X, glee->yGErr)); 98957df6a1bSDebojyoti Ghosh } 99057df6a1bSDebojyoti Ghosh PetscFunctionReturn(0); 99157df6a1bSDebojyoti Ghosh } 99257df6a1bSDebojyoti Ghosh 993*d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSDestroy_GLEE(TS ts) 994*d71ae5a4SJacob Faibussowitsch { 995b3a6b972SJed Brown PetscFunctionBegin; 9969566063dSJacob Faibussowitsch PetscCall(TSReset_GLEE(ts)); 997b3a6b972SJed Brown if (ts->dm) { 9989566063dSJacob Faibussowitsch PetscCall(DMCoarsenHookRemove(ts->dm, DMCoarsenHook_TSGLEE, DMRestrictHook_TSGLEE, ts)); 9999566063dSJacob Faibussowitsch PetscCall(DMSubDomainHookRemove(ts->dm, DMSubDomainHook_TSGLEE, DMSubDomainRestrictHook_TSGLEE, ts)); 1000b3a6b972SJed Brown } 10019566063dSJacob Faibussowitsch PetscCall(PetscFree(ts->data)); 10029566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSGLEEGetType_C", NULL)); 10039566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSGLEESetType_C", NULL)); 1004b3a6b972SJed Brown PetscFunctionReturn(0); 1005b3a6b972SJed Brown } 1006b3a6b972SJed Brown 10072302aa1bSDebojyoti Ghosh /* ------------------------------------------------------------ */ 10082302aa1bSDebojyoti Ghosh /*MC 10092302aa1bSDebojyoti Ghosh TSGLEE - ODE and DAE solver using General Linear with Error Estimation schemes 10102302aa1bSDebojyoti Ghosh 10112302aa1bSDebojyoti Ghosh The user should provide the right hand side of the equation 10122302aa1bSDebojyoti Ghosh using TSSetRHSFunction(). 10132302aa1bSDebojyoti Ghosh 10142302aa1bSDebojyoti Ghosh Notes: 10152302aa1bSDebojyoti Ghosh The default is TSGLEE35, it can be changed with TSGLEESetType() or -ts_glee_type 10162302aa1bSDebojyoti Ghosh 10172302aa1bSDebojyoti Ghosh Level: beginner 10182302aa1bSDebojyoti Ghosh 1019db781477SPatrick Sanan .seealso: `TSCreate()`, `TS`, `TSSetType()`, `TSGLEESetType()`, `TSGLEEGetType()`, 1020db781477SPatrick Sanan `TSGLEE23`, `TTSGLEE24`, `TSGLEE35`, `TSGLEE25I`, `TSGLEEEXRK2A`, 1021db781477SPatrick Sanan `TSGLEERK32G1`, `TSGLEERK285EX`, `TSGLEEType`, `TSGLEERegister()` 10222302aa1bSDebojyoti Ghosh 10232302aa1bSDebojyoti Ghosh M*/ 1024*d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode TSCreate_GLEE(TS ts) 1025*d71ae5a4SJacob Faibussowitsch { 10262302aa1bSDebojyoti Ghosh TS_GLEE *th; 10272302aa1bSDebojyoti Ghosh 10282302aa1bSDebojyoti Ghosh PetscFunctionBegin; 10299566063dSJacob Faibussowitsch PetscCall(TSGLEEInitializePackage()); 10302302aa1bSDebojyoti Ghosh 10312302aa1bSDebojyoti Ghosh ts->ops->reset = TSReset_GLEE; 10322302aa1bSDebojyoti Ghosh ts->ops->destroy = TSDestroy_GLEE; 10332302aa1bSDebojyoti Ghosh ts->ops->view = TSView_GLEE; 10342302aa1bSDebojyoti Ghosh ts->ops->load = TSLoad_GLEE; 10352302aa1bSDebojyoti Ghosh ts->ops->setup = TSSetUp_GLEE; 10362302aa1bSDebojyoti Ghosh ts->ops->step = TSStep_GLEE; 10372302aa1bSDebojyoti Ghosh ts->ops->interpolate = TSInterpolate_GLEE; 10382302aa1bSDebojyoti Ghosh ts->ops->evaluatestep = TSEvaluateStep_GLEE; 10392302aa1bSDebojyoti Ghosh ts->ops->setfromoptions = TSSetFromOptions_GLEE; 10402302aa1bSDebojyoti Ghosh ts->ops->getstages = TSGetStages_GLEE; 10412302aa1bSDebojyoti Ghosh ts->ops->snesfunction = SNESTSFormFunction_GLEE; 10422302aa1bSDebojyoti Ghosh ts->ops->snesjacobian = SNESTSFormJacobian_GLEE; 1043b2bf4f3aSDebojyoti Ghosh ts->ops->getsolutioncomponents = TSGetSolutionComponents_GLEE; 10444cdd57e5SDebojyoti Ghosh ts->ops->getauxsolution = TSGetAuxSolution_GLEE; 10454cdd57e5SDebojyoti Ghosh ts->ops->gettimeerror = TSGetTimeError_GLEE; 104657df6a1bSDebojyoti Ghosh ts->ops->settimeerror = TSSetTimeError_GLEE; 10472302aa1bSDebojyoti Ghosh ts->ops->startingmethod = TSStartingMethod_GLEE; 1048b80d5313SLisandro Dalcin ts->default_adapt_type = TSADAPTGLEE; 10492302aa1bSDebojyoti Ghosh 1050efd4aadfSBarry Smith ts->usessnes = PETSC_TRUE; 1051efd4aadfSBarry Smith 10524dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&th)); 10532302aa1bSDebojyoti Ghosh ts->data = (void *)th; 10542302aa1bSDebojyoti Ghosh 10559566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSGLEEGetType_C", TSGLEEGetType_GLEE)); 10569566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSGLEESetType_C", TSGLEESetType_GLEE)); 10572302aa1bSDebojyoti Ghosh PetscFunctionReturn(0); 10582302aa1bSDebojyoti Ghosh } 1059