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 721cc06b55SBarry Smith .seealso: [](ch_ts), `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 821cc06b55SBarry Smith .seealso: [](ch_ts), `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 921cc06b55SBarry Smith .seealso: [](ch_ts), `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 1021cc06b55SBarry Smith .seealso: [](ch_ts), `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 1121cc06b55SBarry Smith .seealso: [](ch_ts), `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 1221cc06b55SBarry Smith .seealso: [](ch_ts), `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 1321cc06b55SBarry Smith .seealso: [](ch_ts), `TSGLEE` 13336c34d14SEmil Constantinescu M*/ 1342302aa1bSDebojyoti Ghosh 1352302aa1bSDebojyoti Ghosh /*@C 136bcf0153eSBarry Smith 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 1421cc06b55SBarry Smith .seealso: [](ch_ts), `TSGLEERegisterDestroy()` 1432302aa1bSDebojyoti Ghosh @*/ 144d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGLEERegisterAll(void) 145d71ae5a4SJacob Faibussowitsch { 1462302aa1bSDebojyoti Ghosh PetscFunctionBegin; 1473ba16761SJacob Faibussowitsch if (TSGLEERegisterAllCalled) PetscFunctionReturn(PETSC_SUCCESS); 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 } 2803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2812302aa1bSDebojyoti Ghosh } 2822302aa1bSDebojyoti Ghosh 2832302aa1bSDebojyoti Ghosh /*@C 284bcf0153eSBarry Smith TSGLEERegisterDestroy - Frees the list of schemes that were registered by `TSGLEERegister()`. 2852302aa1bSDebojyoti Ghosh 2862302aa1bSDebojyoti Ghosh Not Collective 2872302aa1bSDebojyoti Ghosh 2882302aa1bSDebojyoti Ghosh Level: advanced 2892302aa1bSDebojyoti Ghosh 2901cc06b55SBarry Smith .seealso: [](ch_ts), `TSGLEERegister()`, `TSGLEERegisterAll()` 2912302aa1bSDebojyoti Ghosh @*/ 292d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGLEERegisterDestroy(void) 293d71ae5a4SJacob Faibussowitsch { 2942302aa1bSDebojyoti Ghosh GLEETableauLink link; 2952302aa1bSDebojyoti Ghosh 2962302aa1bSDebojyoti Ghosh PetscFunctionBegin; 2972302aa1bSDebojyoti Ghosh while ((link = GLEETableauList)) { 2982302aa1bSDebojyoti Ghosh GLEETableau t = &link->tab; 2992302aa1bSDebojyoti Ghosh GLEETableauList = link->next; 3009566063dSJacob Faibussowitsch PetscCall(PetscFree5(t->A, t->B, t->U, t->V, t->c)); 301d0609cedSBarry Smith PetscCall(PetscFree2(t->S, t->F)); 302d0609cedSBarry Smith PetscCall(PetscFree(t->Fembed)); 303d0609cedSBarry Smith PetscCall(PetscFree(t->Ferror)); 304d0609cedSBarry Smith PetscCall(PetscFree(t->Serror)); 305d0609cedSBarry Smith PetscCall(PetscFree(t->binterp)); 306d0609cedSBarry Smith PetscCall(PetscFree(t->name)); 307d0609cedSBarry Smith PetscCall(PetscFree(link)); 3082302aa1bSDebojyoti Ghosh } 3092302aa1bSDebojyoti Ghosh TSGLEERegisterAllCalled = PETSC_FALSE; 3103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3112302aa1bSDebojyoti Ghosh } 3122302aa1bSDebojyoti Ghosh 3132302aa1bSDebojyoti Ghosh /*@C 314bcf0153eSBarry Smith TSGLEEInitializePackage - This function initializes everything in the `TSGLEE` package. It is called 315bcf0153eSBarry Smith from `TSInitializePackage()`. 3162302aa1bSDebojyoti Ghosh 3172302aa1bSDebojyoti Ghosh Level: developer 3182302aa1bSDebojyoti Ghosh 3191cc06b55SBarry Smith .seealso: [](ch_ts), `PetscInitialize()` 3202302aa1bSDebojyoti Ghosh @*/ 321d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGLEEInitializePackage(void) 322d71ae5a4SJacob Faibussowitsch { 3232302aa1bSDebojyoti Ghosh PetscFunctionBegin; 3243ba16761SJacob Faibussowitsch if (TSGLEEPackageInitialized) PetscFunctionReturn(PETSC_SUCCESS); 3252302aa1bSDebojyoti Ghosh TSGLEEPackageInitialized = PETSC_TRUE; 3269566063dSJacob Faibussowitsch PetscCall(TSGLEERegisterAll()); 3279566063dSJacob Faibussowitsch PetscCall(PetscObjectComposedDataRegister(&explicit_stage_time_id)); 3289566063dSJacob Faibussowitsch PetscCall(PetscRegisterFinalize(TSGLEEFinalizePackage)); 3293ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3302302aa1bSDebojyoti Ghosh } 3312302aa1bSDebojyoti Ghosh 3322302aa1bSDebojyoti Ghosh /*@C 333bcf0153eSBarry Smith TSGLEEFinalizePackage - This function destroys everything in the `TSGLEE` package. It is 334bcf0153eSBarry Smith called from `PetscFinalize()`. 3352302aa1bSDebojyoti Ghosh 3362302aa1bSDebojyoti Ghosh Level: developer 3372302aa1bSDebojyoti Ghosh 3381cc06b55SBarry Smith .seealso: [](ch_ts), `PetscFinalize()` 3392302aa1bSDebojyoti Ghosh @*/ 340d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGLEEFinalizePackage(void) 341d71ae5a4SJacob Faibussowitsch { 3422302aa1bSDebojyoti Ghosh PetscFunctionBegin; 3432302aa1bSDebojyoti Ghosh TSGLEEPackageInitialized = PETSC_FALSE; 3449566063dSJacob Faibussowitsch PetscCall(TSGLEERegisterDestroy()); 3453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3462302aa1bSDebojyoti Ghosh } 3472302aa1bSDebojyoti Ghosh 3482302aa1bSDebojyoti Ghosh /*@C 349bcf0153eSBarry Smith TSGLEERegister - register a new `TSGLEE` scheme by providing the entries in the Butcher tableau 3502302aa1bSDebojyoti Ghosh 3512302aa1bSDebojyoti Ghosh Not Collective, but the same schemes should be registered on all processes on which they will be used 3522302aa1bSDebojyoti Ghosh 3532302aa1bSDebojyoti Ghosh Input Parameters: 3542302aa1bSDebojyoti Ghosh + name - identifier for method 3552302aa1bSDebojyoti Ghosh . order - order of method 3562302aa1bSDebojyoti Ghosh . s - number of stages 3572302aa1bSDebojyoti Ghosh . r - number of steps 3582302aa1bSDebojyoti Ghosh . gamma - LTE ratio 3592302aa1bSDebojyoti Ghosh . A - stage coefficients (dimension s*s, row-major) 3602302aa1bSDebojyoti Ghosh . B - step completion coefficients (dimension r*s, row-major) 3612302aa1bSDebojyoti Ghosh . U - method coefficients (dimension s*r, row-major) 3622302aa1bSDebojyoti Ghosh . V - method coefficients (dimension r*r, row-major) 3632302aa1bSDebojyoti Ghosh . S - starting coefficients 3642302aa1bSDebojyoti Ghosh . F - finishing coefficients 3652302aa1bSDebojyoti Ghosh . c - abscissa (dimension s; NULL to use row sums of A) 3662302aa1bSDebojyoti Ghosh . Fembed - step completion coefficients for embedded method 367fd96ebc2SDebojyoti Ghosh . Ferror - error computation coefficients 36857df6a1bSDebojyoti Ghosh . Serror - error initialization coefficients 3692302aa1bSDebojyoti Ghosh . pinterp - order of interpolation (0 if unavailable) 3702302aa1bSDebojyoti Ghosh - binterp - array of interpolation coefficients (NULL if unavailable) 3712302aa1bSDebojyoti Ghosh 3722302aa1bSDebojyoti Ghosh Level: advanced 3732302aa1bSDebojyoti Ghosh 374bcf0153eSBarry Smith Note: 375bcf0153eSBarry Smith Several `TSGLEE` methods are provided, this function is only needed to create new methods. 376bcf0153eSBarry Smith 3771cc06b55SBarry Smith .seealso: [](ch_ts), `TSGLEE` 3782302aa1bSDebojyoti Ghosh @*/ 379d71ae5a4SJacob 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[]) 380d71ae5a4SJacob Faibussowitsch { 3812302aa1bSDebojyoti Ghosh GLEETableauLink link; 3822302aa1bSDebojyoti Ghosh GLEETableau t; 3832302aa1bSDebojyoti Ghosh PetscInt i, j; 3842302aa1bSDebojyoti Ghosh 3852302aa1bSDebojyoti Ghosh PetscFunctionBegin; 3869566063dSJacob Faibussowitsch PetscCall(TSGLEEInitializePackage()); 3879566063dSJacob Faibussowitsch PetscCall(PetscNew(&link)); 3882302aa1bSDebojyoti Ghosh t = &link->tab; 3899566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(name, &t->name)); 3902302aa1bSDebojyoti Ghosh t->order = order; 3912302aa1bSDebojyoti Ghosh t->s = s; 3922302aa1bSDebojyoti Ghosh t->r = r; 3932302aa1bSDebojyoti Ghosh t->gamma = gamma; 3949566063dSJacob Faibussowitsch PetscCall(PetscMalloc5(s * s, &t->A, r * r, &t->V, s, &t->c, r * s, &t->B, s * r, &t->U)); 3959566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(r, &t->S, r, &t->F)); 3969566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(t->A, A, s * s)); 3979566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(t->B, B, r * s)); 3989566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(t->U, U, s * r)); 3999566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(t->V, V, r * r)); 4009566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(t->S, S, r)); 4019566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(t->F, F, r)); 4022302aa1bSDebojyoti Ghosh if (c) { 4039566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(t->c, c, s)); 4042302aa1bSDebojyoti Ghosh } else { 4059371c9d4SSatish Balay for (i = 0; i < s; i++) 4069371c9d4SSatish Balay for (j = 0, t->c[i] = 0; j < s; j++) t->c[i] += A[i * s + j]; 4072302aa1bSDebojyoti Ghosh } 4089566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(r, &t->Fembed)); 4099566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(r, &t->Ferror)); 4109566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(r, &t->Serror)); 4119566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(t->Fembed, Fembed, r)); 4129566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(t->Ferror, Ferror, r)); 4139566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(t->Serror, Serror, r)); 4142302aa1bSDebojyoti Ghosh t->pinterp = pinterp; 4159566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(s * pinterp, &t->binterp)); 4169566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(t->binterp, binterp, s * pinterp)); 4172302aa1bSDebojyoti Ghosh 4182302aa1bSDebojyoti Ghosh link->next = GLEETableauList; 4192302aa1bSDebojyoti Ghosh GLEETableauList = link; 4203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4212302aa1bSDebojyoti Ghosh } 4222302aa1bSDebojyoti Ghosh 423d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSEvaluateStep_GLEE(TS ts, PetscInt order, Vec X, PetscBool *done) 424d71ae5a4SJacob Faibussowitsch { 4252302aa1bSDebojyoti Ghosh TS_GLEE *glee = (TS_GLEE *)ts->data; 4262302aa1bSDebojyoti Ghosh GLEETableau tab = glee->tableau; 4279371c9d4SSatish Balay PetscReal h, *B = tab->B, *V = tab->V, *F = tab->F, *Fembed = tab->Fembed; 4282302aa1bSDebojyoti Ghosh PetscInt s = tab->s, r = tab->r, i, j; 4292302aa1bSDebojyoti Ghosh Vec *Y = glee->Y, *YdotStage = glee->YdotStage; 430ec0e3ee2SEmil Constantinescu PetscScalar *ws = glee->swork, *wr = glee->rwork; 4312302aa1bSDebojyoti Ghosh 4322302aa1bSDebojyoti Ghosh PetscFunctionBegin; 4332302aa1bSDebojyoti Ghosh switch (glee->status) { 4342302aa1bSDebojyoti Ghosh case TS_STEP_INCOMPLETE: 435d71ae5a4SJacob Faibussowitsch case TS_STEP_PENDING: 436d71ae5a4SJacob Faibussowitsch h = ts->time_step; 437d71ae5a4SJacob Faibussowitsch break; 438d71ae5a4SJacob Faibussowitsch case TS_STEP_COMPLETE: 439d71ae5a4SJacob Faibussowitsch h = ts->ptime - ts->ptime_prev; 440d71ae5a4SJacob Faibussowitsch break; 441d71ae5a4SJacob Faibussowitsch default: 442d71ae5a4SJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)ts), PETSC_ERR_PLIB, "Invalid TSStepStatus"); 4432302aa1bSDebojyoti Ghosh } 4442302aa1bSDebojyoti Ghosh 4452302aa1bSDebojyoti Ghosh if (order == tab->order) { 4462302aa1bSDebojyoti Ghosh /* Note: Irrespective of whether status is TS_STEP_INCOMPLETE 447fd96ebc2SDebojyoti Ghosh or TS_STEP_COMPLETE, glee->X has the solution at the 4482302aa1bSDebojyoti Ghosh beginning of the time step. So no need to roll-back. 4492302aa1bSDebojyoti Ghosh */ 4502302aa1bSDebojyoti Ghosh if (glee->status == TS_STEP_INCOMPLETE) { 4512302aa1bSDebojyoti Ghosh for (i = 0; i < r; i++) { 4529566063dSJacob Faibussowitsch PetscCall(VecZeroEntries(Y[i])); 453ec0e3ee2SEmil Constantinescu for (j = 0; j < r; j++) wr[j] = V[i * r + j]; 4549566063dSJacob Faibussowitsch PetscCall(VecMAXPY(Y[i], r, wr, glee->X)); 455ec0e3ee2SEmil Constantinescu for (j = 0; j < s; j++) ws[j] = h * B[i * s + j]; 4569566063dSJacob Faibussowitsch PetscCall(VecMAXPY(Y[i], s, ws, YdotStage)); 4572302aa1bSDebojyoti Ghosh } 4589566063dSJacob Faibussowitsch PetscCall(VecZeroEntries(X)); 459ec0e3ee2SEmil Constantinescu for (j = 0; j < r; j++) wr[j] = F[j]; 4609566063dSJacob Faibussowitsch PetscCall(VecMAXPY(X, r, wr, Y)); 4619566063dSJacob Faibussowitsch } else PetscCall(VecCopy(ts->vec_sol, X)); 4623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4632302aa1bSDebojyoti Ghosh 4642302aa1bSDebojyoti Ghosh } else if (order == tab->order - 1) { 4652302aa1bSDebojyoti Ghosh /* Complete with the embedded method (Fembed) */ 4662302aa1bSDebojyoti Ghosh for (i = 0; i < r; i++) { 4679566063dSJacob Faibussowitsch PetscCall(VecZeroEntries(Y[i])); 468ec0e3ee2SEmil Constantinescu for (j = 0; j < r; j++) wr[j] = V[i * r + j]; 4699566063dSJacob Faibussowitsch PetscCall(VecMAXPY(Y[i], r, wr, glee->X)); 470ec0e3ee2SEmil Constantinescu for (j = 0; j < s; j++) ws[j] = h * B[i * s + j]; 4719566063dSJacob Faibussowitsch PetscCall(VecMAXPY(Y[i], s, ws, YdotStage)); 4722302aa1bSDebojyoti Ghosh } 4739566063dSJacob Faibussowitsch PetscCall(VecZeroEntries(X)); 474ec0e3ee2SEmil Constantinescu for (j = 0; j < r; j++) wr[j] = Fembed[j]; 4759566063dSJacob Faibussowitsch PetscCall(VecMAXPY(X, r, wr, Y)); 476fd96ebc2SDebojyoti Ghosh 4772302aa1bSDebojyoti Ghosh if (done) *done = PETSC_TRUE; 4783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4792302aa1bSDebojyoti Ghosh } 4802302aa1bSDebojyoti Ghosh if (done) *done = PETSC_FALSE; 48163a3b9bcSJacob 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); 4823ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4832302aa1bSDebojyoti Ghosh } 4842302aa1bSDebojyoti Ghosh 485d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSStep_GLEE(TS ts) 486d71ae5a4SJacob Faibussowitsch { 4872302aa1bSDebojyoti Ghosh TS_GLEE *glee = (TS_GLEE *)ts->data; 4882302aa1bSDebojyoti Ghosh GLEETableau tab = glee->tableau; 4892302aa1bSDebojyoti Ghosh const PetscInt s = tab->s, r = tab->r; 4909371c9d4SSatish Balay PetscReal *A = tab->A, *U = tab->U, *F = tab->F, *c = tab->c; 4919371c9d4SSatish Balay Vec *Y = glee->Y, *X = glee->X, *YStage = glee->YStage, *YdotStage = glee->YdotStage, W = glee->W; 4922302aa1bSDebojyoti Ghosh SNES snes; 493ec0e3ee2SEmil Constantinescu PetscScalar *ws = glee->swork, *wr = glee->rwork; 4942302aa1bSDebojyoti Ghosh TSAdapt adapt; 4952302aa1bSDebojyoti Ghosh PetscInt i, j, reject, next_scheme, its, lits; 4962302aa1bSDebojyoti Ghosh PetscReal next_time_step; 4972302aa1bSDebojyoti Ghosh PetscReal t; 4982302aa1bSDebojyoti Ghosh PetscBool accept; 4992302aa1bSDebojyoti Ghosh 5002302aa1bSDebojyoti Ghosh PetscFunctionBegin; 5019566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(citation, &cited)); 502642f3702SEmil Constantinescu 5039566063dSJacob Faibussowitsch for (i = 0; i < r; i++) PetscCall(VecCopy(Y[i], X[i])); 5042302aa1bSDebojyoti Ghosh 5059566063dSJacob Faibussowitsch PetscCall(TSGetSNES(ts, &snes)); 5062302aa1bSDebojyoti Ghosh next_time_step = ts->time_step; 5072302aa1bSDebojyoti Ghosh t = ts->ptime; 5082302aa1bSDebojyoti Ghosh accept = PETSC_TRUE; 5092302aa1bSDebojyoti Ghosh glee->status = TS_STEP_INCOMPLETE; 5102302aa1bSDebojyoti Ghosh 5112302aa1bSDebojyoti Ghosh for (reject = 0; reject < ts->max_reject && !ts->reason; reject++, ts->reject++) { 5122302aa1bSDebojyoti Ghosh PetscReal h = ts->time_step; 5139566063dSJacob Faibussowitsch PetscCall(TSPreStep(ts)); 5142302aa1bSDebojyoti Ghosh 5152302aa1bSDebojyoti Ghosh for (i = 0; i < s; i++) { 5162302aa1bSDebojyoti Ghosh glee->stage_time = t + h * c[i]; 5179566063dSJacob Faibussowitsch PetscCall(TSPreStage(ts, glee->stage_time)); 5182302aa1bSDebojyoti Ghosh 5192302aa1bSDebojyoti Ghosh if (A[i * s + i] == 0) { /* Explicit stage */ 5209566063dSJacob Faibussowitsch PetscCall(VecZeroEntries(YStage[i])); 521ec0e3ee2SEmil Constantinescu for (j = 0; j < r; j++) wr[j] = U[i * r + j]; 5229566063dSJacob Faibussowitsch PetscCall(VecMAXPY(YStage[i], r, wr, X)); 523ec0e3ee2SEmil Constantinescu for (j = 0; j < i; j++) ws[j] = h * A[i * s + j]; 5249566063dSJacob Faibussowitsch PetscCall(VecMAXPY(YStage[i], i, ws, YdotStage)); 5252302aa1bSDebojyoti Ghosh } else { /* Implicit stage */ 5262302aa1bSDebojyoti Ghosh glee->scoeff = 1.0 / A[i * s + i]; 5272302aa1bSDebojyoti Ghosh /* compute right-hand-side */ 5289566063dSJacob Faibussowitsch PetscCall(VecZeroEntries(W)); 529ec0e3ee2SEmil Constantinescu for (j = 0; j < r; j++) wr[j] = U[i * r + j]; 5309566063dSJacob Faibussowitsch PetscCall(VecMAXPY(W, r, wr, X)); 531ec0e3ee2SEmil Constantinescu for (j = 0; j < i; j++) ws[j] = h * A[i * s + j]; 5329566063dSJacob Faibussowitsch PetscCall(VecMAXPY(W, i, ws, YdotStage)); 5339566063dSJacob Faibussowitsch PetscCall(VecScale(W, glee->scoeff / h)); 5342302aa1bSDebojyoti Ghosh /* set initial guess */ 5359566063dSJacob Faibussowitsch PetscCall(VecCopy(i > 0 ? YStage[i - 1] : ts->vec_sol, YStage[i])); 5362302aa1bSDebojyoti Ghosh /* solve for this stage */ 5379566063dSJacob Faibussowitsch PetscCall(SNESSolve(snes, W, YStage[i])); 5389566063dSJacob Faibussowitsch PetscCall(SNESGetIterationNumber(snes, &its)); 5399566063dSJacob Faibussowitsch PetscCall(SNESGetLinearSolveIterations(snes, &lits)); 5409371c9d4SSatish Balay ts->snes_its += its; 5419371c9d4SSatish Balay ts->ksp_its += lits; 5422302aa1bSDebojyoti Ghosh } 5439566063dSJacob Faibussowitsch PetscCall(TSGetAdapt(ts, &adapt)); 5449566063dSJacob Faibussowitsch PetscCall(TSAdaptCheckStage(adapt, ts, glee->stage_time, YStage[i], &accept)); 5452302aa1bSDebojyoti Ghosh if (!accept) goto reject_step; 5469566063dSJacob Faibussowitsch PetscCall(TSPostStage(ts, glee->stage_time, i, YStage)); 5479566063dSJacob Faibussowitsch PetscCall(TSComputeRHSFunction(ts, t + h * c[i], YStage[i], YdotStage[i])); 5482302aa1bSDebojyoti Ghosh } 5499566063dSJacob Faibussowitsch PetscCall(TSEvaluateStep(ts, tab->order, ts->vec_sol, NULL)); 5502302aa1bSDebojyoti Ghosh glee->status = TS_STEP_PENDING; 5512302aa1bSDebojyoti Ghosh 5522302aa1bSDebojyoti Ghosh /* Register only the current method as a candidate because we're not supporting multiple candidates yet. */ 5539566063dSJacob Faibussowitsch PetscCall(TSGetAdapt(ts, &adapt)); 5549566063dSJacob Faibussowitsch PetscCall(TSAdaptCandidatesClear(adapt)); 5559566063dSJacob Faibussowitsch PetscCall(TSAdaptCandidateAdd(adapt, tab->name, tab->order, 1, tab->ccfl, (PetscReal)tab->s, PETSC_TRUE)); 5569566063dSJacob Faibussowitsch PetscCall(TSAdaptChoose(adapt, ts, ts->time_step, &next_scheme, &next_time_step, &accept)); 5572302aa1bSDebojyoti Ghosh if (accept) { 5582302aa1bSDebojyoti Ghosh /* ignore next_scheme for now */ 5592302aa1bSDebojyoti Ghosh ts->ptime += ts->time_step; 5602302aa1bSDebojyoti Ghosh ts->time_step = next_time_step; 5612302aa1bSDebojyoti Ghosh glee->status = TS_STEP_COMPLETE; 5620a01e1b2SEmil Constantinescu /* compute and store the global error */ 5630a01e1b2SEmil Constantinescu /* Note: this is not needed if TSAdaptGLEE is not used */ 564*f4f49eeaSPierre Jolivet PetscCall(TSGetTimeError(ts, 0, &glee->yGErr)); 5659566063dSJacob Faibussowitsch PetscCall(PetscObjectComposedDataSetReal((PetscObject)ts->vec_sol, explicit_stage_time_id, ts->ptime)); 5662302aa1bSDebojyoti Ghosh break; 5672302aa1bSDebojyoti Ghosh } else { /* Roll back the current step */ 568ec0e3ee2SEmil Constantinescu for (j = 0; j < r; j++) wr[j] = F[j]; 5699566063dSJacob Faibussowitsch PetscCall(VecMAXPY(ts->vec_sol, r, wr, X)); 5702302aa1bSDebojyoti Ghosh ts->time_step = next_time_step; 5712302aa1bSDebojyoti Ghosh glee->status = TS_STEP_INCOMPLETE; 5722302aa1bSDebojyoti Ghosh } 5739371c9d4SSatish Balay reject_step: 5749371c9d4SSatish Balay continue; 5752302aa1bSDebojyoti Ghosh } 5762302aa1bSDebojyoti Ghosh if (glee->status != TS_STEP_COMPLETE && !ts->reason) ts->reason = TS_DIVERGED_STEP_REJECTED; 5773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5782302aa1bSDebojyoti Ghosh } 5792302aa1bSDebojyoti Ghosh 580d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSInterpolate_GLEE(TS ts, PetscReal itime, Vec X) 581d71ae5a4SJacob Faibussowitsch { 5822302aa1bSDebojyoti Ghosh TS_GLEE *glee = (TS_GLEE *)ts->data; 5832302aa1bSDebojyoti Ghosh PetscInt s = glee->tableau->s, pinterp = glee->tableau->pinterp, i, j; 5842302aa1bSDebojyoti Ghosh PetscReal h, tt, t; 5852302aa1bSDebojyoti Ghosh PetscScalar *b; 5862302aa1bSDebojyoti Ghosh const PetscReal *B = glee->tableau->binterp; 5872302aa1bSDebojyoti Ghosh 5882302aa1bSDebojyoti Ghosh PetscFunctionBegin; 5893c633725SBarry Smith PetscCheck(B, PetscObjectComm((PetscObject)ts), PETSC_ERR_SUP, "TSGLEE %s does not have an interpolation formula", glee->tableau->name); 5902302aa1bSDebojyoti Ghosh switch (glee->status) { 5912302aa1bSDebojyoti Ghosh case TS_STEP_INCOMPLETE: 5922302aa1bSDebojyoti Ghosh case TS_STEP_PENDING: 5932302aa1bSDebojyoti Ghosh h = ts->time_step; 5942302aa1bSDebojyoti Ghosh t = (itime - ts->ptime) / h; 5952302aa1bSDebojyoti Ghosh break; 5962302aa1bSDebojyoti Ghosh case TS_STEP_COMPLETE: 597ed450d42SEmil Constantinescu h = ts->ptime - ts->ptime_prev; 5982302aa1bSDebojyoti Ghosh t = (itime - ts->ptime) / h + 1; /* In the interval [0,1] */ 5992302aa1bSDebojyoti Ghosh break; 600d71ae5a4SJacob Faibussowitsch default: 601d71ae5a4SJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)ts), PETSC_ERR_PLIB, "Invalid TSStepStatus"); 6022302aa1bSDebojyoti Ghosh } 6039566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(s, &b)); 6042302aa1bSDebojyoti Ghosh for (i = 0; i < s; i++) b[i] = 0; 6052302aa1bSDebojyoti Ghosh for (j = 0, tt = t; j < pinterp; j++, tt *= t) { 606ad540459SPierre Jolivet for (i = 0; i < s; i++) b[i] += h * B[i * pinterp + j] * tt; 6072302aa1bSDebojyoti Ghosh } 6089566063dSJacob Faibussowitsch PetscCall(VecCopy(glee->YStage[0], X)); 6099566063dSJacob Faibussowitsch PetscCall(VecMAXPY(X, s, b, glee->YdotStage)); 6109566063dSJacob Faibussowitsch PetscCall(PetscFree(b)); 6113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6122302aa1bSDebojyoti Ghosh } 6132302aa1bSDebojyoti Ghosh 6142302aa1bSDebojyoti Ghosh /*------------------------------------------------------------*/ 615d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSReset_GLEE(TS ts) 616d71ae5a4SJacob Faibussowitsch { 6172302aa1bSDebojyoti Ghosh TS_GLEE *glee = (TS_GLEE *)ts->data; 6182302aa1bSDebojyoti Ghosh PetscInt s, r; 6192302aa1bSDebojyoti Ghosh 6202302aa1bSDebojyoti Ghosh PetscFunctionBegin; 6213ba16761SJacob Faibussowitsch if (!glee->tableau) PetscFunctionReturn(PETSC_SUCCESS); 6222302aa1bSDebojyoti Ghosh s = glee->tableau->s; 6232302aa1bSDebojyoti Ghosh r = glee->tableau->r; 6249566063dSJacob Faibussowitsch PetscCall(VecDestroyVecs(r, &glee->Y)); 6259566063dSJacob Faibussowitsch PetscCall(VecDestroyVecs(r, &glee->X)); 6269566063dSJacob Faibussowitsch PetscCall(VecDestroyVecs(s, &glee->YStage)); 6279566063dSJacob Faibussowitsch PetscCall(VecDestroyVecs(s, &glee->YdotStage)); 6289566063dSJacob Faibussowitsch PetscCall(VecDestroy(&glee->Ydot)); 6299566063dSJacob Faibussowitsch PetscCall(VecDestroy(&glee->yGErr)); 6309566063dSJacob Faibussowitsch PetscCall(VecDestroy(&glee->W)); 6319566063dSJacob Faibussowitsch PetscCall(PetscFree2(glee->swork, glee->rwork)); 6323ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6332302aa1bSDebojyoti Ghosh } 6342302aa1bSDebojyoti Ghosh 635d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSGLEEGetVecs(TS ts, DM dm, Vec *Ydot) 636d71ae5a4SJacob Faibussowitsch { 6372302aa1bSDebojyoti Ghosh TS_GLEE *glee = (TS_GLEE *)ts->data; 6382302aa1bSDebojyoti Ghosh 6392302aa1bSDebojyoti Ghosh PetscFunctionBegin; 6402302aa1bSDebojyoti Ghosh if (Ydot) { 6412302aa1bSDebojyoti Ghosh if (dm && dm != ts->dm) { 6429566063dSJacob Faibussowitsch PetscCall(DMGetNamedGlobalVector(dm, "TSGLEE_Ydot", Ydot)); 6432302aa1bSDebojyoti Ghosh } else *Ydot = glee->Ydot; 6442302aa1bSDebojyoti Ghosh } 6453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6462302aa1bSDebojyoti Ghosh } 6472302aa1bSDebojyoti Ghosh 648d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSGLEERestoreVecs(TS ts, DM dm, Vec *Ydot) 649d71ae5a4SJacob Faibussowitsch { 6502302aa1bSDebojyoti Ghosh PetscFunctionBegin; 6512302aa1bSDebojyoti Ghosh if (Ydot) { 65248a46eb9SPierre Jolivet if (dm && dm != ts->dm) PetscCall(DMRestoreNamedGlobalVector(dm, "TSGLEE_Ydot", Ydot)); 6532302aa1bSDebojyoti Ghosh } 6543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6552302aa1bSDebojyoti Ghosh } 6562302aa1bSDebojyoti Ghosh 6572302aa1bSDebojyoti Ghosh /* 6582302aa1bSDebojyoti Ghosh This defines the nonlinear equation that is to be solved with SNES 6592302aa1bSDebojyoti Ghosh */ 660d71ae5a4SJacob Faibussowitsch static PetscErrorCode SNESTSFormFunction_GLEE(SNES snes, Vec X, Vec F, TS ts) 661d71ae5a4SJacob Faibussowitsch { 6622302aa1bSDebojyoti Ghosh TS_GLEE *glee = (TS_GLEE *)ts->data; 6632302aa1bSDebojyoti Ghosh DM dm, dmsave; 6642302aa1bSDebojyoti Ghosh Vec Ydot; 6652302aa1bSDebojyoti Ghosh PetscReal shift = glee->scoeff / ts->time_step; 6662302aa1bSDebojyoti Ghosh 6672302aa1bSDebojyoti Ghosh PetscFunctionBegin; 6689566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 6699566063dSJacob Faibussowitsch PetscCall(TSGLEEGetVecs(ts, dm, &Ydot)); 6702302aa1bSDebojyoti Ghosh /* Set Ydot = shift*X */ 6719566063dSJacob Faibussowitsch PetscCall(VecCopy(X, Ydot)); 6729566063dSJacob Faibussowitsch PetscCall(VecScale(Ydot, shift)); 6732302aa1bSDebojyoti Ghosh dmsave = ts->dm; 6742302aa1bSDebojyoti Ghosh ts->dm = dm; 6752302aa1bSDebojyoti Ghosh 6769566063dSJacob Faibussowitsch PetscCall(TSComputeIFunction(ts, glee->stage_time, X, Ydot, F, PETSC_FALSE)); 6772302aa1bSDebojyoti Ghosh 6782302aa1bSDebojyoti Ghosh ts->dm = dmsave; 6799566063dSJacob Faibussowitsch PetscCall(TSGLEERestoreVecs(ts, dm, &Ydot)); 6803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6812302aa1bSDebojyoti Ghosh } 6822302aa1bSDebojyoti Ghosh 683d71ae5a4SJacob Faibussowitsch static PetscErrorCode SNESTSFormJacobian_GLEE(SNES snes, Vec X, Mat A, Mat B, TS ts) 684d71ae5a4SJacob Faibussowitsch { 6852302aa1bSDebojyoti Ghosh TS_GLEE *glee = (TS_GLEE *)ts->data; 6862302aa1bSDebojyoti Ghosh DM dm, dmsave; 6872302aa1bSDebojyoti Ghosh Vec Ydot; 6882302aa1bSDebojyoti Ghosh PetscReal shift = glee->scoeff / ts->time_step; 6892302aa1bSDebojyoti Ghosh 6902302aa1bSDebojyoti Ghosh PetscFunctionBegin; 6919566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 6929566063dSJacob Faibussowitsch PetscCall(TSGLEEGetVecs(ts, dm, &Ydot)); 6932302aa1bSDebojyoti Ghosh /* glee->Ydot has already been computed in SNESTSFormFunction_GLEE (SNES guarantees this) */ 6942302aa1bSDebojyoti Ghosh dmsave = ts->dm; 6952302aa1bSDebojyoti Ghosh ts->dm = dm; 6962302aa1bSDebojyoti Ghosh 6979566063dSJacob Faibussowitsch PetscCall(TSComputeIJacobian(ts, glee->stage_time, X, Ydot, shift, A, B, PETSC_FALSE)); 6982302aa1bSDebojyoti Ghosh 6992302aa1bSDebojyoti Ghosh ts->dm = dmsave; 7009566063dSJacob Faibussowitsch PetscCall(TSGLEERestoreVecs(ts, dm, &Ydot)); 7013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7022302aa1bSDebojyoti Ghosh } 7032302aa1bSDebojyoti Ghosh 704d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMCoarsenHook_TSGLEE(DM fine, DM coarse, void *ctx) 705d71ae5a4SJacob Faibussowitsch { 7062302aa1bSDebojyoti Ghosh PetscFunctionBegin; 7073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7082302aa1bSDebojyoti Ghosh } 7092302aa1bSDebojyoti Ghosh 710d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMRestrictHook_TSGLEE(DM fine, Mat restrct, Vec rscale, Mat inject, DM coarse, void *ctx) 711d71ae5a4SJacob Faibussowitsch { 7122302aa1bSDebojyoti Ghosh PetscFunctionBegin; 7133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7142302aa1bSDebojyoti Ghosh } 7152302aa1bSDebojyoti Ghosh 716d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMSubDomainHook_TSGLEE(DM dm, DM subdm, void *ctx) 717d71ae5a4SJacob Faibussowitsch { 7182302aa1bSDebojyoti Ghosh PetscFunctionBegin; 7193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7202302aa1bSDebojyoti Ghosh } 7212302aa1bSDebojyoti Ghosh 722d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMSubDomainRestrictHook_TSGLEE(DM dm, VecScatter gscat, VecScatter lscat, DM subdm, void *ctx) 723d71ae5a4SJacob Faibussowitsch { 7242302aa1bSDebojyoti Ghosh PetscFunctionBegin; 7253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7262302aa1bSDebojyoti Ghosh } 7272302aa1bSDebojyoti Ghosh 728d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSSetUp_GLEE(TS ts) 729d71ae5a4SJacob Faibussowitsch { 7302302aa1bSDebojyoti Ghosh TS_GLEE *glee = (TS_GLEE *)ts->data; 7312302aa1bSDebojyoti Ghosh GLEETableau tab; 7322302aa1bSDebojyoti Ghosh PetscInt s, r; 7332302aa1bSDebojyoti Ghosh DM dm; 7342302aa1bSDebojyoti Ghosh 7352302aa1bSDebojyoti Ghosh PetscFunctionBegin; 73648a46eb9SPierre Jolivet if (!glee->tableau) PetscCall(TSGLEESetType(ts, TSGLEEDefaultType)); 7372302aa1bSDebojyoti Ghosh tab = glee->tableau; 7382302aa1bSDebojyoti Ghosh s = tab->s; 7392302aa1bSDebojyoti Ghosh r = tab->r; 7409566063dSJacob Faibussowitsch PetscCall(VecDuplicateVecs(ts->vec_sol, r, &glee->Y)); 7419566063dSJacob Faibussowitsch PetscCall(VecDuplicateVecs(ts->vec_sol, r, &glee->X)); 7429566063dSJacob Faibussowitsch PetscCall(VecDuplicateVecs(ts->vec_sol, s, &glee->YStage)); 7439566063dSJacob Faibussowitsch PetscCall(VecDuplicateVecs(ts->vec_sol, s, &glee->YdotStage)); 7449566063dSJacob Faibussowitsch PetscCall(VecDuplicate(ts->vec_sol, &glee->Ydot)); 7459566063dSJacob Faibussowitsch PetscCall(VecDuplicate(ts->vec_sol, &glee->yGErr)); 7469566063dSJacob Faibussowitsch PetscCall(VecZeroEntries(glee->yGErr)); 7479566063dSJacob Faibussowitsch PetscCall(VecDuplicate(ts->vec_sol, &glee->W)); 7489566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(s, &glee->swork, r, &glee->rwork)); 7499566063dSJacob Faibussowitsch PetscCall(TSGetDM(ts, &dm)); 7509566063dSJacob Faibussowitsch PetscCall(DMCoarsenHookAdd(dm, DMCoarsenHook_TSGLEE, DMRestrictHook_TSGLEE, ts)); 7519566063dSJacob Faibussowitsch PetscCall(DMSubDomainHookAdd(dm, DMSubDomainHook_TSGLEE, DMSubDomainRestrictHook_TSGLEE, ts)); 7523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7532302aa1bSDebojyoti Ghosh } 7542302aa1bSDebojyoti Ghosh 75566976f2fSJacob Faibussowitsch static PetscErrorCode TSStartingMethod_GLEE(TS ts) 756d71ae5a4SJacob Faibussowitsch { 7572302aa1bSDebojyoti Ghosh TS_GLEE *glee = (TS_GLEE *)ts->data; 7586e2e232bSDebojyoti Ghosh GLEETableau tab = glee->tableau; 7596e2e232bSDebojyoti Ghosh PetscInt r = tab->r, i; 7606e2e232bSDebojyoti Ghosh PetscReal *S = tab->S; 7612302aa1bSDebojyoti Ghosh 7622302aa1bSDebojyoti Ghosh PetscFunctionBegin; 7632302aa1bSDebojyoti Ghosh for (i = 0; i < r; i++) { 7649566063dSJacob Faibussowitsch PetscCall(VecZeroEntries(glee->Y[i])); 7659566063dSJacob Faibussowitsch PetscCall(VecAXPY(glee->Y[i], S[i], ts->vec_sol)); 7662302aa1bSDebojyoti Ghosh } 7673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7682302aa1bSDebojyoti Ghosh } 7692302aa1bSDebojyoti Ghosh 7702302aa1bSDebojyoti Ghosh /*------------------------------------------------------------*/ 7712302aa1bSDebojyoti Ghosh 772d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSSetFromOptions_GLEE(TS ts, PetscOptionItems *PetscOptionsObject) 773d71ae5a4SJacob Faibussowitsch { 7742302aa1bSDebojyoti Ghosh char gleetype[256]; 7752302aa1bSDebojyoti Ghosh 7762302aa1bSDebojyoti Ghosh PetscFunctionBegin; 777d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "GLEE ODE solver options"); 7782302aa1bSDebojyoti Ghosh { 7792302aa1bSDebojyoti Ghosh GLEETableauLink link; 7802302aa1bSDebojyoti Ghosh PetscInt count, choice; 7812302aa1bSDebojyoti Ghosh PetscBool flg; 7822302aa1bSDebojyoti Ghosh const char **namelist; 7832302aa1bSDebojyoti Ghosh 7849566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(gleetype, TSGLEEDefaultType, sizeof(gleetype))); 7859371c9d4SSatish Balay for (link = GLEETableauList, count = 0; link; link = link->next, count++) 7869371c9d4SSatish Balay ; 7879566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(count, (char ***)&namelist)); 7882302aa1bSDebojyoti Ghosh for (link = GLEETableauList, count = 0; link; link = link->next, count++) namelist[count] = link->tab.name; 7899566063dSJacob Faibussowitsch PetscCall(PetscOptionsEList("-ts_glee_type", "Family of GLEE method", "TSGLEESetType", (const char *const *)namelist, count, gleetype, &choice, &flg)); 7909566063dSJacob Faibussowitsch PetscCall(TSGLEESetType(ts, flg ? namelist[choice] : gleetype)); 7919566063dSJacob Faibussowitsch PetscCall(PetscFree(namelist)); 7922302aa1bSDebojyoti Ghosh } 793d0609cedSBarry Smith PetscOptionsHeadEnd(); 7943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7952302aa1bSDebojyoti Ghosh } 7962302aa1bSDebojyoti Ghosh 797d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSView_GLEE(TS ts, PetscViewer viewer) 798d71ae5a4SJacob Faibussowitsch { 7992302aa1bSDebojyoti Ghosh TS_GLEE *glee = (TS_GLEE *)ts->data; 8002302aa1bSDebojyoti Ghosh GLEETableau tab = glee->tableau; 8012302aa1bSDebojyoti Ghosh PetscBool iascii; 8022302aa1bSDebojyoti Ghosh 8032302aa1bSDebojyoti Ghosh PetscFunctionBegin; 8049566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 8052302aa1bSDebojyoti Ghosh if (iascii) { 8062302aa1bSDebojyoti Ghosh TSGLEEType gleetype; 8072302aa1bSDebojyoti Ghosh char buf[512]; 8089566063dSJacob Faibussowitsch PetscCall(TSGLEEGetType(ts, &gleetype)); 8099566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " GLEE type %s\n", gleetype)); 8109566063dSJacob Faibussowitsch PetscCall(PetscFormatRealArray(buf, sizeof(buf), "% 8.6f", tab->s, tab->c)); 8119566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Abscissa c = %s\n", buf)); 8122302aa1bSDebojyoti Ghosh /* Note: print out r as well */ 8132302aa1bSDebojyoti Ghosh } 8143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8152302aa1bSDebojyoti Ghosh } 8162302aa1bSDebojyoti Ghosh 817d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSLoad_GLEE(TS ts, PetscViewer viewer) 818d71ae5a4SJacob Faibussowitsch { 8192302aa1bSDebojyoti Ghosh SNES snes; 8202302aa1bSDebojyoti Ghosh TSAdapt tsadapt; 8212302aa1bSDebojyoti Ghosh 8222302aa1bSDebojyoti Ghosh PetscFunctionBegin; 8239566063dSJacob Faibussowitsch PetscCall(TSGetAdapt(ts, &tsadapt)); 8249566063dSJacob Faibussowitsch PetscCall(TSAdaptLoad(tsadapt, viewer)); 8259566063dSJacob Faibussowitsch PetscCall(TSGetSNES(ts, &snes)); 8269566063dSJacob Faibussowitsch PetscCall(SNESLoad(snes, viewer)); 8272302aa1bSDebojyoti Ghosh /* function and Jacobian context for SNES when used with TS is always ts object */ 8289566063dSJacob Faibussowitsch PetscCall(SNESSetFunction(snes, NULL, NULL, ts)); 8299566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, NULL, NULL, NULL, ts)); 8303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8312302aa1bSDebojyoti Ghosh } 8322302aa1bSDebojyoti Ghosh 8332302aa1bSDebojyoti Ghosh /*@C 834bcf0153eSBarry Smith TSGLEESetType - Set the type of `TSGLEE` scheme 8352302aa1bSDebojyoti Ghosh 83620f4b53cSBarry Smith Logically Collective 8372302aa1bSDebojyoti Ghosh 838d8d19677SJose E. Roman Input Parameters: 8392302aa1bSDebojyoti Ghosh + ts - timestepping context 840bcf0153eSBarry Smith - gleetype - type of `TSGLEE` scheme 8412302aa1bSDebojyoti Ghosh 8422302aa1bSDebojyoti Ghosh Level: intermediate 8432302aa1bSDebojyoti Ghosh 8441cc06b55SBarry Smith .seealso: [](ch_ts), `TSGLEEGetType()`, `TSGLEE` 8452302aa1bSDebojyoti Ghosh @*/ 846d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGLEESetType(TS ts, TSGLEEType gleetype) 847d71ae5a4SJacob Faibussowitsch { 8482302aa1bSDebojyoti Ghosh PetscFunctionBegin; 8492302aa1bSDebojyoti Ghosh PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 8504f572ea9SToby Isaac PetscAssertPointer(gleetype, 2); 851cac4c232SBarry Smith PetscTryMethod(ts, "TSGLEESetType_C", (TS, TSGLEEType), (ts, gleetype)); 8523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8532302aa1bSDebojyoti Ghosh } 8542302aa1bSDebojyoti Ghosh 8552302aa1bSDebojyoti Ghosh /*@C 856bcf0153eSBarry Smith TSGLEEGetType - Get the type of `TSGLEE` scheme 8572302aa1bSDebojyoti Ghosh 85820f4b53cSBarry Smith Logically Collective 8592302aa1bSDebojyoti Ghosh 8602302aa1bSDebojyoti Ghosh Input Parameter: 8612302aa1bSDebojyoti Ghosh . ts - timestepping context 8622302aa1bSDebojyoti Ghosh 8632302aa1bSDebojyoti Ghosh Output Parameter: 864bcf0153eSBarry Smith . gleetype - type of `TSGLEE` scheme 8652302aa1bSDebojyoti Ghosh 8662302aa1bSDebojyoti Ghosh Level: intermediate 8672302aa1bSDebojyoti Ghosh 8681cc06b55SBarry Smith .seealso: [](ch_ts), `TSGLEE`, `TSGLEESetType()` 8692302aa1bSDebojyoti Ghosh @*/ 870d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGLEEGetType(TS ts, TSGLEEType *gleetype) 871d71ae5a4SJacob Faibussowitsch { 8722302aa1bSDebojyoti Ghosh PetscFunctionBegin; 8732302aa1bSDebojyoti Ghosh PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 874cac4c232SBarry Smith PetscUseMethod(ts, "TSGLEEGetType_C", (TS, TSGLEEType *), (ts, gleetype)); 8753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8762302aa1bSDebojyoti Ghosh } 8772302aa1bSDebojyoti Ghosh 87866976f2fSJacob Faibussowitsch static PetscErrorCode TSGLEEGetType_GLEE(TS ts, TSGLEEType *gleetype) 879d71ae5a4SJacob Faibussowitsch { 8802302aa1bSDebojyoti Ghosh TS_GLEE *glee = (TS_GLEE *)ts->data; 8812302aa1bSDebojyoti Ghosh 8822302aa1bSDebojyoti Ghosh PetscFunctionBegin; 88348a46eb9SPierre Jolivet if (!glee->tableau) PetscCall(TSGLEESetType(ts, TSGLEEDefaultType)); 8842302aa1bSDebojyoti Ghosh *gleetype = glee->tableau->name; 8853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8862302aa1bSDebojyoti Ghosh } 88766976f2fSJacob Faibussowitsch static PetscErrorCode TSGLEESetType_GLEE(TS ts, TSGLEEType gleetype) 888d71ae5a4SJacob Faibussowitsch { 8892302aa1bSDebojyoti Ghosh TS_GLEE *glee = (TS_GLEE *)ts->data; 8902302aa1bSDebojyoti Ghosh PetscBool match; 8912302aa1bSDebojyoti Ghosh GLEETableauLink link; 8922302aa1bSDebojyoti Ghosh 8932302aa1bSDebojyoti Ghosh PetscFunctionBegin; 8942302aa1bSDebojyoti Ghosh if (glee->tableau) { 8959566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(glee->tableau->name, gleetype, &match)); 8963ba16761SJacob Faibussowitsch if (match) PetscFunctionReturn(PETSC_SUCCESS); 8972302aa1bSDebojyoti Ghosh } 8982302aa1bSDebojyoti Ghosh for (link = GLEETableauList; link; link = link->next) { 8999566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(link->tab.name, gleetype, &match)); 9002302aa1bSDebojyoti Ghosh if (match) { 9019566063dSJacob Faibussowitsch PetscCall(TSReset_GLEE(ts)); 9022302aa1bSDebojyoti Ghosh glee->tableau = &link->tab; 9033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9042302aa1bSDebojyoti Ghosh } 9052302aa1bSDebojyoti Ghosh } 90698921bdaSJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_UNKNOWN_TYPE, "Could not find '%s'", gleetype); 9072302aa1bSDebojyoti Ghosh } 9082302aa1bSDebojyoti Ghosh 909d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSGetStages_GLEE(TS ts, PetscInt *ns, Vec **Y) 910d71ae5a4SJacob Faibussowitsch { 9112302aa1bSDebojyoti Ghosh TS_GLEE *glee = (TS_GLEE *)ts->data; 9122302aa1bSDebojyoti Ghosh 9132302aa1bSDebojyoti Ghosh PetscFunctionBegin; 9140429704eSStefano Zampini if (ns) *ns = glee->tableau->s; 915d5509560SEmil Constantinescu if (Y) *Y = glee->YStage; 9163ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9172302aa1bSDebojyoti Ghosh } 9182302aa1bSDebojyoti Ghosh 91966976f2fSJacob Faibussowitsch static PetscErrorCode TSGetSolutionComponents_GLEE(TS ts, PetscInt *n, Vec *Y) 920d71ae5a4SJacob Faibussowitsch { 9212302aa1bSDebojyoti Ghosh TS_GLEE *glee = (TS_GLEE *)ts->data; 9222302aa1bSDebojyoti Ghosh GLEETableau tab = glee->tableau; 9232302aa1bSDebojyoti Ghosh 9242302aa1bSDebojyoti Ghosh PetscFunctionBegin; 9254cdd57e5SDebojyoti Ghosh if (!Y) *n = tab->r; 9262302aa1bSDebojyoti Ghosh else { 9274cdd57e5SDebojyoti Ghosh if ((*n >= 0) && (*n < tab->r)) { 9289566063dSJacob Faibussowitsch PetscCall(VecCopy(glee->Y[*n], *Y)); 92963a3b9bcSJacob Faibussowitsch } else SETERRQ(PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_OUTOFRANGE, "Second argument (%" PetscInt_FMT ") out of range[0,%" PetscInt_FMT "].", *n, tab->r - 1); 9302302aa1bSDebojyoti Ghosh } 9313ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9322302aa1bSDebojyoti Ghosh } 9332302aa1bSDebojyoti Ghosh 93466976f2fSJacob Faibussowitsch static PetscErrorCode TSGetAuxSolution_GLEE(TS ts, Vec *X) 935d71ae5a4SJacob Faibussowitsch { 9364cdd57e5SDebojyoti Ghosh TS_GLEE *glee = (TS_GLEE *)ts->data; 9374cdd57e5SDebojyoti Ghosh GLEETableau tab = glee->tableau; 9384cdd57e5SDebojyoti Ghosh PetscReal *F = tab->Fembed; 9394cdd57e5SDebojyoti Ghosh PetscInt r = tab->r; 9404cdd57e5SDebojyoti Ghosh Vec *Y = glee->Y; 941ec0e3ee2SEmil Constantinescu PetscScalar *wr = glee->rwork; 942ec0e3ee2SEmil Constantinescu PetscInt i; 9434cdd57e5SDebojyoti Ghosh 9444cdd57e5SDebojyoti Ghosh PetscFunctionBegin; 9459566063dSJacob Faibussowitsch PetscCall(VecZeroEntries(*X)); 946ec0e3ee2SEmil Constantinescu for (i = 0; i < r; i++) wr[i] = F[i]; 947*f4f49eeaSPierre Jolivet PetscCall(VecMAXPY(*X, r, wr, Y)); 9483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9494cdd57e5SDebojyoti Ghosh } 9504cdd57e5SDebojyoti Ghosh 95166976f2fSJacob Faibussowitsch static PetscErrorCode TSGetTimeError_GLEE(TS ts, PetscInt n, Vec *X) 952d71ae5a4SJacob Faibussowitsch { 9534cdd57e5SDebojyoti Ghosh TS_GLEE *glee = (TS_GLEE *)ts->data; 9544cdd57e5SDebojyoti Ghosh GLEETableau tab = glee->tableau; 9554cdd57e5SDebojyoti Ghosh PetscReal *F = tab->Ferror; 9564cdd57e5SDebojyoti Ghosh PetscInt r = tab->r; 9574cdd57e5SDebojyoti Ghosh Vec *Y = glee->Y; 958ec0e3ee2SEmil Constantinescu PetscScalar *wr = glee->rwork; 959ec0e3ee2SEmil Constantinescu PetscInt i; 9604cdd57e5SDebojyoti Ghosh 9614cdd57e5SDebojyoti Ghosh PetscFunctionBegin; 9629566063dSJacob Faibussowitsch PetscCall(VecZeroEntries(*X)); 963657c1e31SEmil Constantinescu if (n == 0) { 964ec0e3ee2SEmil Constantinescu for (i = 0; i < r; i++) wr[i] = F[i]; 965*f4f49eeaSPierre Jolivet PetscCall(VecMAXPY(*X, r, wr, Y)); 9660a01e1b2SEmil Constantinescu } else if (n == -1) { 967657c1e31SEmil Constantinescu *X = glee->yGErr; 9680a01e1b2SEmil Constantinescu } 9693ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9704cdd57e5SDebojyoti Ghosh } 9714cdd57e5SDebojyoti Ghosh 97266976f2fSJacob Faibussowitsch static PetscErrorCode TSSetTimeError_GLEE(TS ts, Vec X) 973d71ae5a4SJacob Faibussowitsch { 97457df6a1bSDebojyoti Ghosh TS_GLEE *glee = (TS_GLEE *)ts->data; 97557df6a1bSDebojyoti Ghosh GLEETableau tab = glee->tableau; 97657df6a1bSDebojyoti Ghosh PetscReal *S = tab->Serror; 97757df6a1bSDebojyoti Ghosh PetscInt r = tab->r, i; 97857df6a1bSDebojyoti Ghosh Vec *Y = glee->Y; 97957df6a1bSDebojyoti Ghosh 98057df6a1bSDebojyoti Ghosh PetscFunctionBegin; 98163a3b9bcSJacob Faibussowitsch PetscCheck(r == 2, PetscObjectComm((PetscObject)ts), PETSC_ERR_SUP, "TSSetTimeError_GLEE not supported for '%s' with r=%" PetscInt_FMT ".", tab->name, tab->r); 98257df6a1bSDebojyoti Ghosh for (i = 1; i < r; i++) { 9839566063dSJacob Faibussowitsch PetscCall(VecCopy(ts->vec_sol, Y[i])); 9849566063dSJacob Faibussowitsch PetscCall(VecAXPBY(Y[i], S[0], S[1], X)); 9859566063dSJacob Faibussowitsch PetscCall(VecCopy(X, glee->yGErr)); 98657df6a1bSDebojyoti Ghosh } 9873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 98857df6a1bSDebojyoti Ghosh } 98957df6a1bSDebojyoti Ghosh 990d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSDestroy_GLEE(TS ts) 991d71ae5a4SJacob Faibussowitsch { 992b3a6b972SJed Brown PetscFunctionBegin; 9939566063dSJacob Faibussowitsch PetscCall(TSReset_GLEE(ts)); 994b3a6b972SJed Brown if (ts->dm) { 9959566063dSJacob Faibussowitsch PetscCall(DMCoarsenHookRemove(ts->dm, DMCoarsenHook_TSGLEE, DMRestrictHook_TSGLEE, ts)); 9969566063dSJacob Faibussowitsch PetscCall(DMSubDomainHookRemove(ts->dm, DMSubDomainHook_TSGLEE, DMSubDomainRestrictHook_TSGLEE, ts)); 997b3a6b972SJed Brown } 9989566063dSJacob Faibussowitsch PetscCall(PetscFree(ts->data)); 9999566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSGLEEGetType_C", NULL)); 10009566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSGLEESetType_C", NULL)); 10013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1002b3a6b972SJed Brown } 1003b3a6b972SJed Brown 10042302aa1bSDebojyoti Ghosh /* ------------------------------------------------------------ */ 10052302aa1bSDebojyoti Ghosh /*MC 10062302aa1bSDebojyoti Ghosh TSGLEE - ODE and DAE solver using General Linear with Error Estimation schemes 10072302aa1bSDebojyoti Ghosh 1008bcf0153eSBarry Smith The user should provide the right hand side of the equation using `TSSetRHSFunction()`. 10092302aa1bSDebojyoti Ghosh 10102302aa1bSDebojyoti Ghosh Level: beginner 10112302aa1bSDebojyoti Ghosh 1012bcf0153eSBarry Smith Note: 1013bcf0153eSBarry Smith The default is `TSGLEE35`, it can be changed with `TSGLEESetType()` or -ts_glee_type 10142302aa1bSDebojyoti Ghosh 10151cc06b55SBarry Smith .seealso: [](ch_ts), `TSCreate()`, `TS`, `TSSetType()`, `TSGLEESetType()`, `TSGLEEGetType()`, 1016bcf0153eSBarry Smith `TSGLEE23`, `TTSGLEE24`, `TSGLEE35`, `TSGLEE25I`, `TSGLEEEXRK2A`, 1017bcf0153eSBarry Smith `TSGLEERK32G1`, `TSGLEERK285EX`, `TSGLEEType`, `TSGLEERegister()`, `TSType` 10182302aa1bSDebojyoti Ghosh M*/ 1019d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode TSCreate_GLEE(TS ts) 1020d71ae5a4SJacob Faibussowitsch { 10212302aa1bSDebojyoti Ghosh TS_GLEE *th; 10222302aa1bSDebojyoti Ghosh 10232302aa1bSDebojyoti Ghosh PetscFunctionBegin; 10249566063dSJacob Faibussowitsch PetscCall(TSGLEEInitializePackage()); 10252302aa1bSDebojyoti Ghosh 10262302aa1bSDebojyoti Ghosh ts->ops->reset = TSReset_GLEE; 10272302aa1bSDebojyoti Ghosh ts->ops->destroy = TSDestroy_GLEE; 10282302aa1bSDebojyoti Ghosh ts->ops->view = TSView_GLEE; 10292302aa1bSDebojyoti Ghosh ts->ops->load = TSLoad_GLEE; 10302302aa1bSDebojyoti Ghosh ts->ops->setup = TSSetUp_GLEE; 10312302aa1bSDebojyoti Ghosh ts->ops->step = TSStep_GLEE; 10322302aa1bSDebojyoti Ghosh ts->ops->interpolate = TSInterpolate_GLEE; 10332302aa1bSDebojyoti Ghosh ts->ops->evaluatestep = TSEvaluateStep_GLEE; 10342302aa1bSDebojyoti Ghosh ts->ops->setfromoptions = TSSetFromOptions_GLEE; 10352302aa1bSDebojyoti Ghosh ts->ops->getstages = TSGetStages_GLEE; 10362302aa1bSDebojyoti Ghosh ts->ops->snesfunction = SNESTSFormFunction_GLEE; 10372302aa1bSDebojyoti Ghosh ts->ops->snesjacobian = SNESTSFormJacobian_GLEE; 1038b2bf4f3aSDebojyoti Ghosh ts->ops->getsolutioncomponents = TSGetSolutionComponents_GLEE; 10394cdd57e5SDebojyoti Ghosh ts->ops->getauxsolution = TSGetAuxSolution_GLEE; 10404cdd57e5SDebojyoti Ghosh ts->ops->gettimeerror = TSGetTimeError_GLEE; 104157df6a1bSDebojyoti Ghosh ts->ops->settimeerror = TSSetTimeError_GLEE; 10422302aa1bSDebojyoti Ghosh ts->ops->startingmethod = TSStartingMethod_GLEE; 1043b80d5313SLisandro Dalcin ts->default_adapt_type = TSADAPTGLEE; 10442302aa1bSDebojyoti Ghosh 1045efd4aadfSBarry Smith ts->usessnes = PETSC_TRUE; 1046efd4aadfSBarry Smith 10474dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&th)); 10482302aa1bSDebojyoti Ghosh ts->data = (void *)th; 10492302aa1bSDebojyoti Ghosh 10509566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSGLEEGetType_C", TSGLEEGetType_GLEE)); 10519566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSGLEESetType_C", TSGLEESetType_GLEE)); 10523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 10532302aa1bSDebojyoti Ghosh } 1054