1e27a552bSJed Brown /* 261692a83SJed Brown Code for timestepping with Rosenbrock W methods 3e27a552bSJed Brown 4e27a552bSJed Brown Notes: 5e27a552bSJed Brown The general system is written as 6e27a552bSJed Brown 7f9c1d6abSBarry Smith F(t,U,Udot) = G(t,U) 8e27a552bSJed Brown 9f9c1d6abSBarry Smith where F represents the stiff part of the physics and G represents the non-stiff part. 10f9c1d6abSBarry Smith This method is designed to be linearly implicit on F and can use an approximate and lagged Jacobian. 11e27a552bSJed Brown 12e27a552bSJed Brown */ 13af0996ceSBarry Smith #include <petsc/private/tsimpl.h> /*I "petscts.h" I*/ 141e25c274SJed Brown #include <petscdm.h> 15e27a552bSJed Brown 16af0996ceSBarry Smith #include <petsc/private/kernels/blockinvert.h> 1761692a83SJed Brown 1819fd82e9SBarry Smith static TSRosWType TSRosWDefault = TSROSWRA34PW2; 19e27a552bSJed Brown static PetscBool TSRosWRegisterAllCalled; 20e27a552bSJed Brown static PetscBool TSRosWPackageInitialized; 21e27a552bSJed Brown 2261692a83SJed Brown typedef struct _RosWTableau *RosWTableau; 2361692a83SJed Brown struct _RosWTableau { 24e27a552bSJed Brown char *name; 25e27a552bSJed Brown PetscInt order; /* Classical approximation order of the method */ 26e27a552bSJed Brown PetscInt s; /* Number of stages */ 27f4aed992SEmil Constantinescu PetscInt pinterp; /* Interpolation order */ 2861692a83SJed Brown PetscReal *A; /* Propagation table, strictly lower triangular */ 2961692a83SJed Brown PetscReal *Gamma; /* Stage table, lower triangular with nonzero diagonal */ 30c17803e7SJed Brown PetscBool *GammaZeroDiag; /* Diagonal entries that are zero in stage table Gamma, vector indicating explicit statages */ 3143b21953SEmil Constantinescu PetscReal *GammaExplicitCorr; /* Coefficients for correction terms needed for explicit stages in transformed variables*/ 3261692a83SJed Brown PetscReal *b; /* Step completion table */ 33fe7e6d57SJed Brown PetscReal *bembed; /* Step completion table for embedded method of order one less */ 3461692a83SJed Brown PetscReal *ASum; /* Row sum of A */ 3561692a83SJed Brown PetscReal *GammaSum; /* Row sum of Gamma, only needed for non-autonomous systems */ 3661692a83SJed Brown PetscReal *At; /* Propagation table in transformed variables */ 3761692a83SJed Brown PetscReal *bt; /* Step completion table in transformed variables */ 38fe7e6d57SJed Brown PetscReal *bembedt; /* Step completion table of order one less in transformed variables */ 3961692a83SJed Brown PetscReal *GammaInv; /* Inverse of Gamma, used for transformed variables */ 408d59e960SJed Brown PetscReal ccfl; /* Placeholder for CFL coefficient relative to forward Euler */ 413ca35412SEmil Constantinescu PetscReal *binterpt; /* Dense output formula */ 42e27a552bSJed Brown }; 4361692a83SJed Brown typedef struct _RosWTableauLink *RosWTableauLink; 4461692a83SJed Brown struct _RosWTableauLink { 4561692a83SJed Brown struct _RosWTableau tab; 4661692a83SJed Brown RosWTableauLink next; 47e27a552bSJed Brown }; 4861692a83SJed Brown static RosWTableauLink RosWTableauList; 49e27a552bSJed Brown 50e27a552bSJed Brown typedef struct { 5161692a83SJed Brown RosWTableau tableau; 5261692a83SJed Brown Vec *Y; /* States computed during the step, used to complete the step */ 53e27a552bSJed Brown Vec Ydot; /* Work vector holding Ydot during residual evaluation */ 5461692a83SJed Brown Vec Ystage; /* Work vector for the state value at each stage */ 5561692a83SJed Brown Vec Zdot; /* Ydot = Zdot + shift*Y */ 5661692a83SJed Brown Vec Zstage; /* Y = Zstage + Y */ 57be5899b3SLisandro Dalcin Vec vec_sol_prev; /* Solution from the previous step (used for interpolation and rollback)*/ 581c3436cfSJed Brown PetscScalar *work; /* Scalar work space of length number of stages, used to prepare VecMAXPY() */ 59b296d7d5SJed Brown PetscReal scoeff; /* shift = scoeff/dt */ 60e27a552bSJed Brown PetscReal stage_time; 61c17803e7SJed Brown PetscReal stage_explicit; /* Flag indicates that the current stage is explicit */ 6261692a83SJed Brown PetscBool recompute_jacobian; /* Recompute the Jacobian at each stage, default is to freeze the Jacobian at the start of each step */ 63108c343cSJed Brown TSStepStatus status; 64e27a552bSJed Brown } TS_RosW; 65e27a552bSJed Brown 66fe7e6d57SJed Brown /*MC 673606a31eSEmil Constantinescu TSROSWTHETA1 - One stage first order L-stable Rosenbrock-W scheme (aka theta method). 683606a31eSEmil Constantinescu 693606a31eSEmil Constantinescu Only an approximate Jacobian is needed. 703606a31eSEmil Constantinescu 713606a31eSEmil Constantinescu Level: intermediate 723606a31eSEmil Constantinescu 731cc06b55SBarry Smith .seealso: [](ch_ts), `TSROSW` 743606a31eSEmil Constantinescu M*/ 753606a31eSEmil Constantinescu 763606a31eSEmil Constantinescu /*MC 773606a31eSEmil Constantinescu TSROSWTHETA2 - One stage second order A-stable Rosenbrock-W scheme (aka theta method). 783606a31eSEmil Constantinescu 793606a31eSEmil Constantinescu Only an approximate Jacobian is needed. 803606a31eSEmil Constantinescu 813606a31eSEmil Constantinescu Level: intermediate 823606a31eSEmil Constantinescu 831cc06b55SBarry Smith .seealso: [](ch_ts), `TSROSW` 843606a31eSEmil Constantinescu M*/ 853606a31eSEmil Constantinescu 863606a31eSEmil Constantinescu /*MC 87fe7e6d57SJed Brown TSROSW2M - Two stage second order L-stable Rosenbrock-W scheme. 88fe7e6d57SJed Brown 89fe7e6d57SJed Brown Only an approximate Jacobian is needed. By default, it is only recomputed once per step. This method is a reflection of TSROSW2P. 90fe7e6d57SJed Brown 91fe7e6d57SJed Brown Level: intermediate 92fe7e6d57SJed Brown 931cc06b55SBarry Smith .seealso: [](ch_ts), `TSROSW` 94fe7e6d57SJed Brown M*/ 95fe7e6d57SJed Brown 96fe7e6d57SJed Brown /*MC 97fe7e6d57SJed Brown TSROSW2P - Two stage second order L-stable Rosenbrock-W scheme. 98fe7e6d57SJed Brown 99fe7e6d57SJed Brown Only an approximate Jacobian is needed. By default, it is only recomputed once per step. This method is a reflection of TSROSW2M. 100fe7e6d57SJed Brown 101fe7e6d57SJed Brown Level: intermediate 102fe7e6d57SJed Brown 1031cc06b55SBarry Smith .seealso: [](ch_ts), `TSROSW` 104fe7e6d57SJed Brown M*/ 105fe7e6d57SJed Brown 106fe7e6d57SJed Brown /*MC 1071d27aa22SBarry Smith TSROSWRA3PW - Three stage third order Rosenbrock-W scheme for PDAE of index 1 {cite}`rang_2005` 108fe7e6d57SJed Brown 109fe7e6d57SJed Brown Only an approximate Jacobian is needed. By default, it is only recomputed once per step. 110fe7e6d57SJed Brown 111fe7e6d57SJed Brown This is strongly A-stable with R(infty) = 0.73. The embedded method of order 2 is strongly A-stable with R(infty) = 0.73. 112fe7e6d57SJed Brown 113bcf0153eSBarry Smith Level: intermediate 114bcf0153eSBarry Smith 1151cc06b55SBarry Smith .seealso: [](ch_ts), `TSROSW` 116fe7e6d57SJed Brown M*/ 117fe7e6d57SJed Brown 118fe7e6d57SJed Brown /*MC 1191d27aa22SBarry Smith TSROSWRA34PW2 - Four stage third order L-stable Rosenbrock-W scheme for PDAE of index 1 {cite}`rang_2005`. 120fe7e6d57SJed Brown 121fe7e6d57SJed Brown Only an approximate Jacobian is needed. By default, it is only recomputed once per step. 122fe7e6d57SJed Brown 123fe7e6d57SJed Brown This is strongly A-stable with R(infty) = 0. The embedded method of order 2 is strongly A-stable with R(infty) = 0.48. 124fe7e6d57SJed Brown 125bcf0153eSBarry Smith Level: intermediate 126bcf0153eSBarry Smith 1271cc06b55SBarry Smith .seealso: [](ch_ts), `TSROSW` 128fe7e6d57SJed Brown M*/ 129fe7e6d57SJed Brown 130ef3c5b88SJed Brown /*MC 1311d27aa22SBarry Smith TSROSWRODAS3 - Four stage third order L-stable Rosenbrock scheme {cite}`sandu_1997` 132ef3c5b88SJed Brown 133ef3c5b88SJed Brown By default, the Jacobian is only recomputed once per step. 134ef3c5b88SJed Brown 135ef3c5b88SJed Brown Both the third order and embedded second order methods are stiffly accurate and L-stable. 136ef3c5b88SJed Brown 137bcf0153eSBarry Smith Level: intermediate 138bcf0153eSBarry Smith 1391cc06b55SBarry Smith .seealso: [](ch_ts), `TSROSW`, `TSROSWSANDU3` 140ef3c5b88SJed Brown M*/ 141ef3c5b88SJed Brown 142ef3c5b88SJed Brown /*MC 143*48665b53SJed Brown TSROSWRODASPR - Six stage fourth order L-stable Rosenbrock scheme {cite}`rang2015improved` 144*48665b53SJed Brown 145*48665b53SJed Brown By default, the Jacobian is only recomputed once per step. 146*48665b53SJed Brown 147*48665b53SJed Brown Both the fourth order and embedded third order methods are stiffly accurate and L-stable. 148*48665b53SJed Brown The method is B_{PR} consistent of order 3, which ensures convergence order for non-stiff, medium stiff, and stiff problems. 149*48665b53SJed Brown 150*48665b53SJed Brown Level: intermediate 151*48665b53SJed Brown 152*48665b53SJed Brown .seealso: [](ch_ts), `TSROSW`, `TSROSWSANDU3` 153*48665b53SJed Brown M*/ 154*48665b53SJed Brown 155*48665b53SJed Brown /*MC 1561d27aa22SBarry Smith TSROSWSANDU3 - Three stage third order L-stable Rosenbrock scheme {cite}`sandu_1997` 157ef3c5b88SJed Brown 158ef3c5b88SJed Brown By default, the Jacobian is only recomputed once per step. 159ef3c5b88SJed Brown 160ef3c5b88SJed Brown The third order method is L-stable, but not stiffly accurate. 161ef3c5b88SJed Brown The second order embedded method is strongly A-stable with R(infty) = 0.5. 162ef3c5b88SJed Brown The internal stages are L-stable. 1631d27aa22SBarry Smith This method is called ROS3 in {cite}`sandu_1997`. 164ef3c5b88SJed Brown 165bcf0153eSBarry Smith Level: intermediate 166bcf0153eSBarry Smith 1671cc06b55SBarry Smith .seealso: [](ch_ts), `TSROSW`, `TSROSWRODAS3` 168ef3c5b88SJed Brown M*/ 169ef3c5b88SJed Brown 170961f28d0SJed Brown /*MC 171961f28d0SJed Brown TSROSWASSP3P3S1C - A-stable Rosenbrock-W method with SSP explicit part, third order, three stages 172961f28d0SJed Brown 173961f28d0SJed Brown By default, the Jacobian is only recomputed once per step. 174961f28d0SJed Brown 175961f28d0SJed Brown A-stable SPP explicit order 3, 3 stages, CFL 1 (eff = 1/3) 176961f28d0SJed Brown 177bcf0153eSBarry Smith Level: intermediate 178bcf0153eSBarry Smith 1791cc06b55SBarry Smith .seealso: [](ch_ts), `TSROSW`, `TSROSWLASSP3P4S2C`, `TSROSWLLSSP3P4S2C`, `SSP` 180961f28d0SJed Brown M*/ 181961f28d0SJed Brown 182961f28d0SJed Brown /*MC 183998eb97aSJed Brown TSROSWLASSP3P4S2C - L-stable Rosenbrock-W method with SSP explicit part, third order, four stages 184961f28d0SJed Brown 185961f28d0SJed Brown By default, the Jacobian is only recomputed once per step. 186961f28d0SJed Brown 187961f28d0SJed Brown L-stable (A-stable embedded) SPP explicit order 3, 4 stages, CFL 2 (eff = 1/2) 188961f28d0SJed Brown 189bcf0153eSBarry Smith Level: intermediate 190bcf0153eSBarry Smith 1911cc06b55SBarry Smith .seealso: [](ch_ts), `TSROSW`, `TSROSWASSP3P3S1C`, `TSROSWLLSSP3P4S2C`, `TSSSP` 192961f28d0SJed Brown M*/ 193961f28d0SJed Brown 194961f28d0SJed Brown /*MC 195998eb97aSJed Brown TSROSWLLSSP3P4S2C - L-stable Rosenbrock-W method with SSP explicit part, third order, four stages 196961f28d0SJed Brown 197961f28d0SJed Brown By default, the Jacobian is only recomputed once per step. 198961f28d0SJed Brown 199961f28d0SJed Brown L-stable (L-stable embedded) SPP explicit order 3, 4 stages, CFL 2 (eff = 1/2) 200961f28d0SJed Brown 201bcf0153eSBarry Smith Level: intermediate 202bcf0153eSBarry Smith 2031cc06b55SBarry Smith .seealso: [](ch_ts), `TSROSW`, `TSROSWASSP3P3S1C`, `TSROSWLASSP3P4S2C`, `TSSSP` 204961f28d0SJed Brown M*/ 205961f28d0SJed Brown 20642faf41dSJed Brown /*MC 2071d27aa22SBarry Smith TSROSWGRK4T - four stage, fourth order Rosenbrock (not W) method from Kaps and Rentrop {cite}`kaps1979generalized` 20842faf41dSJed Brown 20942faf41dSJed Brown By default, the Jacobian is only recomputed once per step. 21042faf41dSJed Brown 21142faf41dSJed Brown A(89.3 degrees)-stable, |R(infty)| = 0.454. 21242faf41dSJed Brown 21342faf41dSJed Brown This method does not provide a dense output formula. 21442faf41dSJed Brown 215bcf0153eSBarry Smith Level: intermediate 216bcf0153eSBarry Smith 2171d27aa22SBarry Smith Note: 2181d27aa22SBarry Smith See Section 4 Table 7.2 in {cite}`wanner1996solving` 21942faf41dSJed Brown 2201cc06b55SBarry Smith .seealso: [](ch_ts), `TSROSW`, `TSROSWSHAMP4`, `TSROSWVELDD4`, `TSROSW4L` 22142faf41dSJed Brown M*/ 22242faf41dSJed Brown 22342faf41dSJed Brown /*MC 2241d27aa22SBarry Smith TSROSWSHAMP4 - four stage, fourth order Rosenbrock (not W) method from Shampine {cite}`shampine1982implementation` 22542faf41dSJed Brown 22642faf41dSJed Brown By default, the Jacobian is only recomputed once per step. 22742faf41dSJed Brown 22842faf41dSJed Brown A-stable, |R(infty)| = 1/3. 22942faf41dSJed Brown 23042faf41dSJed Brown This method does not provide a dense output formula. 23142faf41dSJed Brown 232bcf0153eSBarry Smith Level: intermediate 233bcf0153eSBarry Smith 2341d27aa22SBarry Smith Note: 23515229ffcSPierre Jolivet See Section 4 Table 7.2 in {cite}`wanner1996solving` 23642faf41dSJed Brown 2371cc06b55SBarry Smith .seealso: [](ch_ts), `TSROSW`, `TSROSWGRK4T`, `TSROSWVELDD4`, `TSROSW4L` 23842faf41dSJed Brown M*/ 23942faf41dSJed Brown 24042faf41dSJed Brown /*MC 2411d27aa22SBarry Smith TSROSWVELDD4 - four stage, fourth order Rosenbrock (not W) method from van Veldhuizen {cite}`veldhuizen1984d` 24242faf41dSJed Brown 24342faf41dSJed Brown By default, the Jacobian is only recomputed once per step. 24442faf41dSJed Brown 24542faf41dSJed Brown A(89.5 degrees)-stable, |R(infty)| = 0.24. 24642faf41dSJed Brown 24742faf41dSJed Brown This method does not provide a dense output formula. 24842faf41dSJed Brown 249bcf0153eSBarry Smith Level: intermediate 250bcf0153eSBarry Smith 2511d27aa22SBarry Smith Note: 2521d27aa22SBarry Smith See Section 4 Table 7.2 in {cite}`wanner1996solving` 25342faf41dSJed Brown 2541cc06b55SBarry Smith .seealso: [](ch_ts), `TSROSW`, `TSROSWGRK4T`, `TSROSWSHAMP4`, `TSROSW4L` 25542faf41dSJed Brown M*/ 25642faf41dSJed Brown 25742faf41dSJed Brown /*MC 25842faf41dSJed Brown TSROSW4L - four stage, fourth order Rosenbrock (not W) method 25942faf41dSJed Brown 26042faf41dSJed Brown By default, the Jacobian is only recomputed once per step. 26142faf41dSJed Brown 26242faf41dSJed Brown A-stable and L-stable 26342faf41dSJed Brown 26442faf41dSJed Brown This method does not provide a dense output formula. 26542faf41dSJed Brown 266bcf0153eSBarry Smith Level: intermediate 267bcf0153eSBarry Smith 2681d27aa22SBarry Smith Note: 26915229ffcSPierre Jolivet See Section 4 Table 7.2 in {cite}`wanner1996solving` 27042faf41dSJed Brown 2711cc06b55SBarry Smith .seealso: [](ch_ts), `TSROSW`, `TSROSWGRK4T`, `TSROSWSHAMP4`, `TSROSW4L` 27242faf41dSJed Brown M*/ 27342faf41dSJed Brown 274e27a552bSJed Brown /*@C 275bcf0153eSBarry Smith TSRosWRegisterAll - Registers all of the Rosenbrock-W methods in `TSROSW` 276e27a552bSJed Brown 2771d27aa22SBarry Smith Not Collective, but should be called by all MPI processes which will need the schemes to be registered 278e27a552bSJed Brown 279e27a552bSJed Brown Level: advanced 280e27a552bSJed Brown 2811cc06b55SBarry Smith .seealso: [](ch_ts), `TSROSW`, `TSRosWRegisterDestroy()` 282e27a552bSJed Brown @*/ 283d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRosWRegisterAll(void) 284d71ae5a4SJacob Faibussowitsch { 285e27a552bSJed Brown PetscFunctionBegin; 2863ba16761SJacob Faibussowitsch if (TSRosWRegisterAllCalled) PetscFunctionReturn(PETSC_SUCCESS); 287e27a552bSJed Brown TSRosWRegisterAllCalled = PETSC_TRUE; 288e27a552bSJed Brown 289e27a552bSJed Brown { 290bbd56ea5SKarl Rupp const PetscReal A = 0; 291bbd56ea5SKarl Rupp const PetscReal Gamma = 1; 292bbd56ea5SKarl Rupp const PetscReal b = 1; 293bbd56ea5SKarl Rupp const PetscReal binterpt = 1; 2941f80e275SEmil Constantinescu 2959566063dSJacob Faibussowitsch PetscCall(TSRosWRegister(TSROSWTHETA1, 1, 1, &A, &Gamma, &b, NULL, 1, &binterpt)); 2963606a31eSEmil Constantinescu } 2973606a31eSEmil Constantinescu 2983606a31eSEmil Constantinescu { 299bbd56ea5SKarl Rupp const PetscReal A = 0; 300bbd56ea5SKarl Rupp const PetscReal Gamma = 0.5; 301bbd56ea5SKarl Rupp const PetscReal b = 1; 302bbd56ea5SKarl Rupp const PetscReal binterpt = 1; 303bbd56ea5SKarl Rupp 3049566063dSJacob Faibussowitsch PetscCall(TSRosWRegister(TSROSWTHETA2, 2, 1, &A, &Gamma, &b, NULL, 1, &binterpt)); 3053606a31eSEmil Constantinescu } 3063606a31eSEmil Constantinescu 3073606a31eSEmil Constantinescu { 308da80777bSKarl Rupp /*const PetscReal g = 1. + 1./PetscSqrtReal(2.0); Direct evaluation: 1.707106781186547524401. Used for setting up arrays of values known at compile time below. */ 309b16ce868SStefano Zampini const PetscReal A[2][2] = { 3109371c9d4SSatish Balay {0, 0}, 3119371c9d4SSatish Balay {1., 0} 312b16ce868SStefano Zampini }; 313b16ce868SStefano Zampini const PetscReal Gamma[2][2] = { 314b16ce868SStefano Zampini {1.707106781186547524401, 0 }, 315b16ce868SStefano Zampini {-2. * 1.707106781186547524401, 1.707106781186547524401} 316b16ce868SStefano Zampini }; 317b16ce868SStefano Zampini const PetscReal b[2] = {0.5, 0.5}; 318b16ce868SStefano Zampini const PetscReal b1[2] = {1.0, 0.0}; 3191f80e275SEmil Constantinescu PetscReal binterpt[2][2]; 320da80777bSKarl Rupp binterpt[0][0] = 1.707106781186547524401 - 1.0; 321da80777bSKarl Rupp binterpt[1][0] = 2.0 - 1.707106781186547524401; 322da80777bSKarl Rupp binterpt[0][1] = 1.707106781186547524401 - 1.5; 323da80777bSKarl Rupp binterpt[1][1] = 1.5 - 1.707106781186547524401; 324bbd56ea5SKarl Rupp 3259566063dSJacob Faibussowitsch PetscCall(TSRosWRegister(TSROSW2P, 2, 2, &A[0][0], &Gamma[0][0], b, b1, 2, &binterpt[0][0])); 326e27a552bSJed Brown } 327e27a552bSJed Brown { 328da80777bSKarl Rupp /*const PetscReal g = 1. - 1./PetscSqrtReal(2.0); Direct evaluation: 0.2928932188134524755992. Used for setting up arrays of values known at compile time below. */ 329b16ce868SStefano Zampini const PetscReal A[2][2] = { 3309371c9d4SSatish Balay {0, 0}, 3319371c9d4SSatish Balay {1., 0} 332b16ce868SStefano Zampini }; 333b16ce868SStefano Zampini const PetscReal Gamma[2][2] = { 334b16ce868SStefano Zampini {0.2928932188134524755992, 0 }, 335b16ce868SStefano Zampini {-2. * 0.2928932188134524755992, 0.2928932188134524755992} 336b16ce868SStefano Zampini }; 337b16ce868SStefano Zampini const PetscReal b[2] = {0.5, 0.5}; 338b16ce868SStefano Zampini const PetscReal b1[2] = {1.0, 0.0}; 3391f80e275SEmil Constantinescu PetscReal binterpt[2][2]; 340da80777bSKarl Rupp binterpt[0][0] = 0.2928932188134524755992 - 1.0; 341da80777bSKarl Rupp binterpt[1][0] = 2.0 - 0.2928932188134524755992; 342da80777bSKarl Rupp binterpt[0][1] = 0.2928932188134524755992 - 1.5; 343da80777bSKarl Rupp binterpt[1][1] = 1.5 - 0.2928932188134524755992; 344bbd56ea5SKarl Rupp 3459566063dSJacob Faibussowitsch PetscCall(TSRosWRegister(TSROSW2M, 2, 2, &A[0][0], &Gamma[0][0], b, b1, 2, &binterpt[0][0])); 346fe7e6d57SJed Brown } 347fe7e6d57SJed Brown { 348da80777bSKarl Rupp /*const PetscReal g = 7.8867513459481287e-01; Directly written in-place below */ 3491f80e275SEmil Constantinescu PetscReal binterpt[3][2]; 350b16ce868SStefano Zampini const PetscReal A[3][3] = { 3519371c9d4SSatish Balay {0, 0, 0}, 352fe7e6d57SJed Brown {1.5773502691896257e+00, 0, 0}, 3539371c9d4SSatish Balay {0.5, 0, 0} 354b16ce868SStefano Zampini }; 355b16ce868SStefano Zampini const PetscReal Gamma[3][3] = { 356b16ce868SStefano Zampini {7.8867513459481287e-01, 0, 0 }, 357b16ce868SStefano Zampini {-1.5773502691896257e+00, 7.8867513459481287e-01, 0 }, 358b16ce868SStefano Zampini {-6.7075317547305480e-01, -1.7075317547305482e-01, 7.8867513459481287e-01} 359b16ce868SStefano Zampini }; 360b16ce868SStefano Zampini const PetscReal b[3] = {1.0566243270259355e-01, 4.9038105676657971e-02, 8.4529946162074843e-01}; 361b16ce868SStefano Zampini const PetscReal b2[3] = {-1.7863279495408180e-01, 1. / 3., 8.4529946162074843e-01}; 3621f80e275SEmil Constantinescu 3631f80e275SEmil Constantinescu binterpt[0][0] = -0.8094010767585034; 3641f80e275SEmil Constantinescu binterpt[1][0] = -0.5; 3651f80e275SEmil Constantinescu binterpt[2][0] = 2.3094010767585034; 3661f80e275SEmil Constantinescu binterpt[0][1] = 0.9641016151377548; 3671f80e275SEmil Constantinescu binterpt[1][1] = 0.5; 3681f80e275SEmil Constantinescu binterpt[2][1] = -1.4641016151377548; 369bbd56ea5SKarl Rupp 3709566063dSJacob Faibussowitsch PetscCall(TSRosWRegister(TSROSWRA3PW, 3, 3, &A[0][0], &Gamma[0][0], b, b2, 2, &binterpt[0][0])); 371fe7e6d57SJed Brown } 372fe7e6d57SJed Brown { 3733ca35412SEmil Constantinescu PetscReal binterpt[4][3]; 374da80777bSKarl Rupp /*const PetscReal g = 4.3586652150845900e-01; Directly written in-place below */ 375b16ce868SStefano Zampini const PetscReal A[4][4] = { 3769371c9d4SSatish Balay {0, 0, 0, 0}, 377fe7e6d57SJed Brown {8.7173304301691801e-01, 0, 0, 0}, 378fe7e6d57SJed Brown {8.4457060015369423e-01, -1.1299064236484185e-01, 0, 0}, 3799371c9d4SSatish Balay {0, 0, 1., 0} 380b16ce868SStefano Zampini }; 381b16ce868SStefano Zampini const PetscReal Gamma[4][4] = { 382b16ce868SStefano Zampini {4.3586652150845900e-01, 0, 0, 0 }, 383b16ce868SStefano Zampini {-8.7173304301691801e-01, 4.3586652150845900e-01, 0, 0 }, 384b16ce868SStefano Zampini {-9.0338057013044082e-01, 5.4180672388095326e-02, 4.3586652150845900e-01, 0 }, 385b16ce868SStefano Zampini {2.4212380706095346e-01, -1.2232505839045147e+00, 5.4526025533510214e-01, 4.3586652150845900e-01} 386b16ce868SStefano Zampini }; 387b16ce868SStefano Zampini const PetscReal b[4] = {2.4212380706095346e-01, -1.2232505839045147e+00, 1.5452602553351020e+00, 4.3586652150845900e-01}; 388b16ce868SStefano Zampini const PetscReal b2[4] = {3.7810903145819369e-01, -9.6042292212423178e-02, 5.0000000000000000e-01, 2.1793326075422950e-01}; 3893ca35412SEmil Constantinescu 3903ca35412SEmil Constantinescu binterpt[0][0] = 1.0564298455794094; 3913ca35412SEmil Constantinescu binterpt[1][0] = 2.296429974281067; 3923ca35412SEmil Constantinescu binterpt[2][0] = -1.307599564525376; 3933ca35412SEmil Constantinescu binterpt[3][0] = -1.045260255335102; 3943ca35412SEmil Constantinescu binterpt[0][1] = -1.3864882699759573; 3953ca35412SEmil Constantinescu binterpt[1][1] = -8.262611700275677; 3963ca35412SEmil Constantinescu binterpt[2][1] = 7.250979895056055; 3973ca35412SEmil Constantinescu binterpt[3][1] = 2.398120075195581; 3983ca35412SEmil Constantinescu binterpt[0][2] = 0.5721822314575016; 3993ca35412SEmil Constantinescu binterpt[1][2] = 4.742931142090097; 4003ca35412SEmil Constantinescu binterpt[2][2] = -4.398120075195578; 4013ca35412SEmil Constantinescu binterpt[3][2] = -0.9169932983520199; 4023ca35412SEmil Constantinescu 4039566063dSJacob Faibussowitsch PetscCall(TSRosWRegister(TSROSWRA34PW2, 3, 4, &A[0][0], &Gamma[0][0], b, b2, 3, &binterpt[0][0])); 404e27a552bSJed Brown } 405ef3c5b88SJed Brown { 406da80777bSKarl Rupp /* const PetscReal g = 0.5; Directly written in-place below */ 407b16ce868SStefano Zampini const PetscReal A[4][4] = { 4089371c9d4SSatish Balay {0, 0, 0, 0}, 409ef3c5b88SJed Brown {0, 0, 0, 0}, 410ef3c5b88SJed Brown {1., 0, 0, 0}, 4119371c9d4SSatish Balay {0.75, -0.25, 0.5, 0} 412b16ce868SStefano Zampini }; 413b16ce868SStefano Zampini const PetscReal Gamma[4][4] = { 414b16ce868SStefano Zampini {0.5, 0, 0, 0 }, 415b16ce868SStefano Zampini {1., 0.5, 0, 0 }, 416b16ce868SStefano Zampini {-0.25, -0.25, 0.5, 0 }, 417b16ce868SStefano Zampini {1. / 12, 1. / 12, -2. / 3, 0.5} 418b16ce868SStefano Zampini }; 419b16ce868SStefano Zampini const PetscReal b[4] = {5. / 6, -1. / 6, -1. / 6, 0.5}; 420b16ce868SStefano Zampini const PetscReal b2[4] = {0.75, -0.25, 0.5, 0}; 421bbd56ea5SKarl Rupp 4229566063dSJacob Faibussowitsch PetscCall(TSRosWRegister(TSROSWRODAS3, 3, 4, &A[0][0], &Gamma[0][0], b, b2, 0, NULL)); 423ef3c5b88SJed Brown } 424ef3c5b88SJed Brown { 425*48665b53SJed Brown /* const PetscReal g = 0.25; Directly written in-place below */ 426*48665b53SJed Brown const PetscReal A[6][6] = { 427*48665b53SJed Brown {0, 0, 0, 0, 0, 0}, 428*48665b53SJed Brown {0.75, 0, 0, 0, 0, 0}, 429*48665b53SJed Brown {7.5162877593868457e-02, 2.4837122406131545e-02, 0, 0, 0, 0}, 430*48665b53SJed Brown {1.6532708886396510e+00, 2.1545706385445562e-01, -1.3157488872766792e+00, 0, 0, 0}, 431*48665b53SJed Brown {1.9385003738039885e+01, 1.2007117225835324e+00, -1.9337924059522791e+01, -2.4779140110062559e-01, 0, 0}, 432*48665b53SJed Brown {-7.3844531665375115e+00, -3.0593419030174646e-01, 7.8622074209377981e+00, 5.7817993590145966e-01, 0.25, 0} 433*48665b53SJed Brown }; 434*48665b53SJed Brown const PetscReal Gamma[6][6] = { 435*48665b53SJed Brown {0.25, 0, 0, 0, 0, 0 }, 436*48665b53SJed Brown {-7.5000000000000000e-01, 0.25, 0, 0, 0, 0 }, 437*48665b53SJed Brown {-8.8644359075349941e-02, -2.8688974257983398e-02, 0.25, 0, 0, 0 }, 438*48665b53SJed Brown {-4.8470034585330284e+00, -3.1583244269672095e-01, 4.9536568360123221e+00, 0.25, 0, 0 }, 439*48665b53SJed Brown {-2.6769456904577400e+01, -1.5066459128852787e+00, 2.7200131480460591e+01, 8.2597133700208525e-01, 0.25, 0 }, 440*48665b53SJed Brown {6.5876206496361416e+00, 3.6807059172993878e-01, -6.7423520694658121e+00, -1.0619631475741095e-01, -3.5714285714285715e-01, 0.25} 441*48665b53SJed Brown }; 442*48665b53SJed Brown const PetscReal b[6] = {-7.9683251690137014e-01, 6.2136401428192344e-02, 1.1198553514719862e+00, 4.7198362114404874e-01, -1.0714285714285714e-01, 0.25}; 443*48665b53SJed Brown const PetscReal b2[6] = {-7.3844531665375115e+00, -3.0593419030174646e-01, 7.8622074209377981e+00, 5.7817993590145966e-01, 0.25, 0.0}; 444*48665b53SJed Brown 445*48665b53SJed Brown PetscCall(TSRosWRegister(TSROSWRODASPR, 4, 6, &A[0][0], &Gamma[0][0], b, b2, 0, NULL)); 446*48665b53SJed Brown } 447*48665b53SJed Brown { 448da80777bSKarl Rupp /*const PetscReal g = 0.43586652150845899941601945119356; Directly written in-place below */ 449b16ce868SStefano Zampini const PetscReal A[3][3] = { 4509371c9d4SSatish Balay {0, 0, 0}, 451da80777bSKarl Rupp {0.43586652150845899941601945119356, 0, 0}, 4529371c9d4SSatish Balay {0.43586652150845899941601945119356, 0, 0} 453b16ce868SStefano Zampini }; 454b16ce868SStefano Zampini const PetscReal Gamma[3][3] = { 455b16ce868SStefano Zampini {0.43586652150845899941601945119356, 0, 0 }, 456b16ce868SStefano Zampini {-0.19294655696029095575009695436041, 0.43586652150845899941601945119356, 0 }, 457b16ce868SStefano Zampini {0, 1.74927148125794685173529749738960, 0.43586652150845899941601945119356} 458b16ce868SStefano Zampini }; 459b16ce868SStefano Zampini const PetscReal b[3] = {-0.75457412385404315829818998646589, 1.94100407061964420292840123379419, -0.18642994676560104463021124732829}; 460b16ce868SStefano Zampini const PetscReal b2[3] = {-1.53358745784149585370766523913002, 2.81745131148625772213931745457622, -0.28386385364476186843165221544619}; 4611f80e275SEmil Constantinescu 4621f80e275SEmil Constantinescu PetscReal binterpt[3][2]; 4631f80e275SEmil Constantinescu binterpt[0][0] = 3.793692883777660870425141387941; 4641f80e275SEmil Constantinescu binterpt[1][0] = -2.918692883777660870425141387941; 4651f80e275SEmil Constantinescu binterpt[2][0] = 0.125; 4661f80e275SEmil Constantinescu binterpt[0][1] = -0.725741064379812106687651020584; 4671f80e275SEmil Constantinescu binterpt[1][1] = 0.559074397713145440020984353917; 4681f80e275SEmil Constantinescu binterpt[2][1] = 0.16666666666666666666666666666667; 4691f80e275SEmil Constantinescu 4709566063dSJacob Faibussowitsch PetscCall(TSRosWRegister(TSROSWSANDU3, 3, 3, &A[0][0], &Gamma[0][0], b, b2, 2, &binterpt[0][0])); 471ef3c5b88SJed Brown } 472b1c69cc3SEmil Constantinescu { 473da80777bSKarl Rupp /*const PetscReal s3 = PetscSqrtReal(3.),g = (3.0+s3)/6.0; 474da80777bSKarl Rupp * Direct evaluation: s3 = 1.732050807568877293527; 475da80777bSKarl Rupp * g = 0.7886751345948128822546; 476da80777bSKarl Rupp * Values are directly inserted below to ensure availability at compile time (compiler warnings otherwise...) */ 477b16ce868SStefano Zampini const PetscReal A[3][3] = { 4789371c9d4SSatish Balay {0, 0, 0}, 479b1c69cc3SEmil Constantinescu {1, 0, 0}, 4809371c9d4SSatish Balay {0.25, 0.25, 0} 481b16ce868SStefano Zampini }; 482b16ce868SStefano Zampini const PetscReal Gamma[3][3] = { 483b16ce868SStefano Zampini {0, 0, 0 }, 484b16ce868SStefano Zampini {(-3.0 - 1.732050807568877293527) / 6.0, 0.7886751345948128822546, 0 }, 485b16ce868SStefano Zampini {(-3.0 - 1.732050807568877293527) / 24.0, (-3.0 - 1.732050807568877293527) / 8.0, 0.7886751345948128822546} 486b16ce868SStefano Zampini }; 487b16ce868SStefano Zampini const PetscReal b[3] = {1. / 6., 1. / 6., 2. / 3.}; 488b16ce868SStefano Zampini const PetscReal b2[3] = {1. / 4., 1. / 4., 1. / 2.}; 489c0cb691aSEmil Constantinescu PetscReal binterpt[3][2]; 490da80777bSKarl Rupp 491c0cb691aSEmil Constantinescu binterpt[0][0] = 0.089316397477040902157517886164709; 492c0cb691aSEmil Constantinescu binterpt[1][0] = -0.91068360252295909784248211383529; 493c0cb691aSEmil Constantinescu binterpt[2][0] = 1.8213672050459181956849642276706; 494c0cb691aSEmil Constantinescu binterpt[0][1] = 0.077350269189625764509148780501957; 495c0cb691aSEmil Constantinescu binterpt[1][1] = 1.077350269189625764509148780502; 496c0cb691aSEmil Constantinescu binterpt[2][1] = -1.1547005383792515290182975610039; 497bbd56ea5SKarl Rupp 4989566063dSJacob Faibussowitsch PetscCall(TSRosWRegister(TSROSWASSP3P3S1C, 3, 3, &A[0][0], &Gamma[0][0], b, b2, 2, &binterpt[0][0])); 499b1c69cc3SEmil Constantinescu } 500b1c69cc3SEmil Constantinescu 501b1c69cc3SEmil Constantinescu { 502b16ce868SStefano Zampini const PetscReal A[4][4] = { 5039371c9d4SSatish Balay {0, 0, 0, 0}, 504b1c69cc3SEmil Constantinescu {1. / 2., 0, 0, 0}, 505b1c69cc3SEmil Constantinescu {1. / 2., 1. / 2., 0, 0}, 5069371c9d4SSatish Balay {1. / 6., 1. / 6., 1. / 6., 0} 507b16ce868SStefano Zampini }; 508b16ce868SStefano Zampini const PetscReal Gamma[4][4] = { 509b16ce868SStefano Zampini {1. / 2., 0, 0, 0}, 510b16ce868SStefano Zampini {0.0, 1. / 4., 0, 0}, 511b16ce868SStefano Zampini {-2., -2. / 3., 2. / 3., 0}, 512b16ce868SStefano Zampini {1. / 2., 5. / 36., -2. / 9, 0} 513b16ce868SStefano Zampini }; 514b16ce868SStefano Zampini const PetscReal b[4] = {1. / 6., 1. / 6., 1. / 6., 1. / 2.}; 515b16ce868SStefano Zampini const PetscReal b2[4] = {1. / 8., 3. / 4., 1. / 8., 0}; 516c0cb691aSEmil Constantinescu PetscReal binterpt[4][3]; 517da80777bSKarl Rupp 518c0cb691aSEmil Constantinescu binterpt[0][0] = 6.25; 519c0cb691aSEmil Constantinescu binterpt[1][0] = -30.25; 520c0cb691aSEmil Constantinescu binterpt[2][0] = 1.75; 521c0cb691aSEmil Constantinescu binterpt[3][0] = 23.25; 522c0cb691aSEmil Constantinescu binterpt[0][1] = -9.75; 523c0cb691aSEmil Constantinescu binterpt[1][1] = 58.75; 524c0cb691aSEmil Constantinescu binterpt[2][1] = -3.25; 525c0cb691aSEmil Constantinescu binterpt[3][1] = -45.75; 526c0cb691aSEmil Constantinescu binterpt[0][2] = 3.6666666666666666666666666666667; 527c0cb691aSEmil Constantinescu binterpt[1][2] = -28.333333333333333333333333333333; 528c0cb691aSEmil Constantinescu binterpt[2][2] = 1.6666666666666666666666666666667; 529c0cb691aSEmil Constantinescu binterpt[3][2] = 23.; 530bbd56ea5SKarl Rupp 5319566063dSJacob Faibussowitsch PetscCall(TSRosWRegister(TSROSWLASSP3P4S2C, 3, 4, &A[0][0], &Gamma[0][0], b, b2, 3, &binterpt[0][0])); 532b1c69cc3SEmil Constantinescu } 533b1c69cc3SEmil Constantinescu 534b1c69cc3SEmil Constantinescu { 535b16ce868SStefano Zampini const PetscReal A[4][4] = { 5369371c9d4SSatish Balay {0, 0, 0, 0}, 537b1c69cc3SEmil Constantinescu {1. / 2., 0, 0, 0}, 538b1c69cc3SEmil Constantinescu {1. / 2., 1. / 2., 0, 0}, 5399371c9d4SSatish Balay {1. / 6., 1. / 6., 1. / 6., 0} 540b16ce868SStefano Zampini }; 541b16ce868SStefano Zampini const PetscReal Gamma[4][4] = { 542b16ce868SStefano Zampini {1. / 2., 0, 0, 0}, 543b16ce868SStefano Zampini {0.0, 3. / 4., 0, 0}, 544b16ce868SStefano Zampini {-2. / 3., -23. / 9., 2. / 9., 0}, 545b16ce868SStefano Zampini {1. / 18., 65. / 108., -2. / 27, 0} 546b16ce868SStefano Zampini }; 547b16ce868SStefano Zampini const PetscReal b[4] = {1. / 6., 1. / 6., 1. / 6., 1. / 2.}; 548b16ce868SStefano Zampini const PetscReal b2[4] = {3. / 16., 10. / 16., 3. / 16., 0}; 549c0cb691aSEmil Constantinescu PetscReal binterpt[4][3]; 550da80777bSKarl Rupp 551c0cb691aSEmil Constantinescu binterpt[0][0] = 1.6911764705882352941176470588235; 552c0cb691aSEmil Constantinescu binterpt[1][0] = 3.6813725490196078431372549019608; 553c0cb691aSEmil Constantinescu binterpt[2][0] = 0.23039215686274509803921568627451; 554c0cb691aSEmil Constantinescu binterpt[3][0] = -4.6029411764705882352941176470588; 555c0cb691aSEmil Constantinescu binterpt[0][1] = -0.95588235294117647058823529411765; 556c0cb691aSEmil Constantinescu binterpt[1][1] = -6.2401960784313725490196078431373; 557c0cb691aSEmil Constantinescu binterpt[2][1] = -0.31862745098039215686274509803922; 558c0cb691aSEmil Constantinescu binterpt[3][1] = 7.5147058823529411764705882352941; 559c0cb691aSEmil Constantinescu binterpt[0][2] = -0.56862745098039215686274509803922; 560c0cb691aSEmil Constantinescu binterpt[1][2] = 2.7254901960784313725490196078431; 561c0cb691aSEmil Constantinescu binterpt[2][2] = 0.25490196078431372549019607843137; 562c0cb691aSEmil Constantinescu binterpt[3][2] = -2.4117647058823529411764705882353; 563bbd56ea5SKarl Rupp 5649566063dSJacob Faibussowitsch PetscCall(TSRosWRegister(TSROSWLLSSP3P4S2C, 3, 4, &A[0][0], &Gamma[0][0], b, b2, 3, &binterpt[0][0])); 565b1c69cc3SEmil Constantinescu } 566753f8adbSEmil Constantinescu 567753f8adbSEmil Constantinescu { 568753f8adbSEmil Constantinescu PetscReal A[4][4], Gamma[4][4], b[4], b2[4]; 5693ca35412SEmil Constantinescu PetscReal binterpt[4][3]; 570753f8adbSEmil Constantinescu 571753f8adbSEmil Constantinescu Gamma[0][0] = 0.4358665215084589994160194475295062513822671686978816; 5729371c9d4SSatish Balay Gamma[0][1] = 0; 5739371c9d4SSatish Balay Gamma[0][2] = 0; 5749371c9d4SSatish Balay Gamma[0][3] = 0; 575753f8adbSEmil Constantinescu Gamma[1][0] = -1.997527830934941248426324674704153457289527280554476; 576753f8adbSEmil Constantinescu Gamma[1][1] = 0.4358665215084589994160194475295062513822671686978816; 5779371c9d4SSatish Balay Gamma[1][2] = 0; 5789371c9d4SSatish Balay Gamma[1][3] = 0; 579753f8adbSEmil Constantinescu Gamma[2][0] = -1.007948511795029620852002345345404191008352770119903; 580753f8adbSEmil Constantinescu Gamma[2][1] = -0.004648958462629345562774289390054679806993396798458131; 581753f8adbSEmil Constantinescu Gamma[2][2] = 0.4358665215084589994160194475295062513822671686978816; 58205e8e825SJed Brown Gamma[2][3] = 0; 583753f8adbSEmil Constantinescu Gamma[3][0] = -0.6685429734233467180451604600279552604364311322650783; 584753f8adbSEmil Constantinescu Gamma[3][1] = 0.6056625986449338476089525334450053439525178740492984; 585753f8adbSEmil Constantinescu Gamma[3][2] = -0.9717899277217721234705114616271378792182450260943198; 586753f8adbSEmil Constantinescu Gamma[3][3] = 0; 587753f8adbSEmil Constantinescu 5889371c9d4SSatish Balay A[0][0] = 0; 5899371c9d4SSatish Balay A[0][1] = 0; 5909371c9d4SSatish Balay A[0][2] = 0; 5919371c9d4SSatish Balay A[0][3] = 0; 592753f8adbSEmil Constantinescu A[1][0] = 0.8717330430169179988320388950590125027645343373957631; 5939371c9d4SSatish Balay A[1][1] = 0; 5949371c9d4SSatish Balay A[1][2] = 0; 5959371c9d4SSatish Balay A[1][3] = 0; 596753f8adbSEmil Constantinescu A[2][0] = 0.5275890119763004115618079766722914408876108660811028; 597753f8adbSEmil Constantinescu A[2][1] = 0.07241098802369958843819203208518599088698057726988732; 5989371c9d4SSatish Balay A[2][2] = 0; 5999371c9d4SSatish Balay A[2][3] = 0; 600753f8adbSEmil Constantinescu A[3][0] = 0.3990960076760701320627260685975778145384666450351314; 601753f8adbSEmil Constantinescu A[3][1] = -0.4375576546135194437228463747348862825846903771419953; 602753f8adbSEmil Constantinescu A[3][2] = 1.038461646937449311660120300601880176655352737312713; 60305e8e825SJed Brown A[3][3] = 0; 604753f8adbSEmil Constantinescu 605753f8adbSEmil Constantinescu b[0] = 0.1876410243467238251612921333138006734899663569186926; 606753f8adbSEmil Constantinescu b[1] = -0.5952974735769549480478230473706443582188442040780541; 607753f8adbSEmil Constantinescu b[2] = 0.9717899277217721234705114616271378792182450260943198; 608753f8adbSEmil Constantinescu b[3] = 0.4358665215084589994160194475295062513822671686978816; 609753f8adbSEmil Constantinescu 610753f8adbSEmil Constantinescu b2[0] = 0.2147402862233891404862383521089097657790734483804460; 611753f8adbSEmil Constantinescu b2[1] = -0.4851622638849390928209050538171743017757490232519684; 612753f8adbSEmil Constantinescu b2[2] = 0.8687250025203875511662123688667549217531982787600080; 613753f8adbSEmil Constantinescu b2[3] = 0.4016969751411624011684543450940068201770721128357014; 614753f8adbSEmil Constantinescu 6153ca35412SEmil Constantinescu binterpt[0][0] = 2.2565812720167954547104627844105; 6163ca35412SEmil Constantinescu binterpt[1][0] = 1.349166413351089573796243820819; 6173ca35412SEmil Constantinescu binterpt[2][0] = -2.4695174540533503758652847586647; 6183ca35412SEmil Constantinescu binterpt[3][0] = -0.13623023131453465264142184656474; 6193ca35412SEmil Constantinescu binterpt[0][1] = -3.0826699111559187902922463354557; 6203ca35412SEmil Constantinescu binterpt[1][1] = -2.4689115685996042534544925650515; 6213ca35412SEmil Constantinescu binterpt[2][1] = 5.7428279814696677152129332773553; 6223ca35412SEmil Constantinescu binterpt[3][1] = -0.19124650171414467146619437684812; 6233ca35412SEmil Constantinescu binterpt[0][2] = 1.0137296634858471607430756831148; 6243ca35412SEmil Constantinescu binterpt[1][2] = 0.52444768167155973161042570784064; 6253ca35412SEmil Constantinescu binterpt[2][2] = -2.3015205996945452158771370439586; 6263ca35412SEmil Constantinescu binterpt[3][2] = 0.76334325453713832352363565300308; 627f4aed992SEmil Constantinescu 6289566063dSJacob Faibussowitsch PetscCall(TSRosWRegister(TSROSWARK3, 3, 4, &A[0][0], &Gamma[0][0], b, b2, 3, &binterpt[0][0])); 629753f8adbSEmil Constantinescu } 6309566063dSJacob Faibussowitsch PetscCall(TSRosWRegisterRos4(TSROSWGRK4T, 0.231, PETSC_DEFAULT, PETSC_DEFAULT, 0, -0.1282612945269037e+01)); 6319566063dSJacob Faibussowitsch PetscCall(TSRosWRegisterRos4(TSROSWSHAMP4, 0.5, PETSC_DEFAULT, PETSC_DEFAULT, 0, 125. / 108.)); 6329566063dSJacob Faibussowitsch PetscCall(TSRosWRegisterRos4(TSROSWVELDD4, 0.22570811482256823492, PETSC_DEFAULT, PETSC_DEFAULT, 0, -1.355958941201148)); 6339566063dSJacob Faibussowitsch PetscCall(TSRosWRegisterRos4(TSROSW4L, 0.57282, PETSC_DEFAULT, PETSC_DEFAULT, 0, -1.093502252409163)); 6343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 635e27a552bSJed Brown } 636e27a552bSJed Brown 637e27a552bSJed Brown /*@C 638bcf0153eSBarry Smith TSRosWRegisterDestroy - Frees the list of schemes that were registered by `TSRosWRegister()`. 639e27a552bSJed Brown 640e27a552bSJed Brown Not Collective 641e27a552bSJed Brown 642e27a552bSJed Brown Level: advanced 643e27a552bSJed Brown 6441cc06b55SBarry Smith .seealso: [](ch_ts), `TSRosWRegister()`, `TSRosWRegisterAll()` 645e27a552bSJed Brown @*/ 646d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRosWRegisterDestroy(void) 647d71ae5a4SJacob Faibussowitsch { 64861692a83SJed Brown RosWTableauLink link; 649e27a552bSJed Brown 650e27a552bSJed Brown PetscFunctionBegin; 65161692a83SJed Brown while ((link = RosWTableauList)) { 65261692a83SJed Brown RosWTableau t = &link->tab; 65361692a83SJed Brown RosWTableauList = link->next; 6549566063dSJacob Faibussowitsch PetscCall(PetscFree5(t->A, t->Gamma, t->b, t->ASum, t->GammaSum)); 6559566063dSJacob Faibussowitsch PetscCall(PetscFree5(t->At, t->bt, t->GammaInv, t->GammaZeroDiag, t->GammaExplicitCorr)); 6569566063dSJacob Faibussowitsch PetscCall(PetscFree2(t->bembed, t->bembedt)); 6579566063dSJacob Faibussowitsch PetscCall(PetscFree(t->binterpt)); 6589566063dSJacob Faibussowitsch PetscCall(PetscFree(t->name)); 6599566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 660e27a552bSJed Brown } 661e27a552bSJed Brown TSRosWRegisterAllCalled = PETSC_FALSE; 6623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 663e27a552bSJed Brown } 664e27a552bSJed Brown 665e27a552bSJed Brown /*@C 666bcf0153eSBarry Smith TSRosWInitializePackage - This function initializes everything in the `TSROSW` package. It is called 667bcf0153eSBarry Smith from `TSInitializePackage()`. 668e27a552bSJed Brown 669e27a552bSJed Brown Level: developer 670e27a552bSJed Brown 6711cc06b55SBarry Smith .seealso: [](ch_ts), `TSROSW`, `PetscInitialize()`, `TSRosWFinalizePackage()` 672e27a552bSJed Brown @*/ 673d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRosWInitializePackage(void) 674d71ae5a4SJacob Faibussowitsch { 675e27a552bSJed Brown PetscFunctionBegin; 6763ba16761SJacob Faibussowitsch if (TSRosWPackageInitialized) PetscFunctionReturn(PETSC_SUCCESS); 677e27a552bSJed Brown TSRosWPackageInitialized = PETSC_TRUE; 6789566063dSJacob Faibussowitsch PetscCall(TSRosWRegisterAll()); 6799566063dSJacob Faibussowitsch PetscCall(PetscRegisterFinalize(TSRosWFinalizePackage)); 6803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 681e27a552bSJed Brown } 682e27a552bSJed Brown 683e27a552bSJed Brown /*@C 684bcf0153eSBarry Smith TSRosWFinalizePackage - This function destroys everything in the `TSROSW` package. It is 685bcf0153eSBarry Smith called from `PetscFinalize()`. 686e27a552bSJed Brown 687e27a552bSJed Brown Level: developer 688e27a552bSJed Brown 6891cc06b55SBarry Smith .seealso: [](ch_ts), `TSROSW`, `PetscFinalize()`, `TSRosWInitializePackage()` 690e27a552bSJed Brown @*/ 691d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRosWFinalizePackage(void) 692d71ae5a4SJacob Faibussowitsch { 693e27a552bSJed Brown PetscFunctionBegin; 694e27a552bSJed Brown TSRosWPackageInitialized = PETSC_FALSE; 6959566063dSJacob Faibussowitsch PetscCall(TSRosWRegisterDestroy()); 6963ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 697e27a552bSJed Brown } 698e27a552bSJed Brown 699e27a552bSJed Brown /*@C 700bcf0153eSBarry Smith TSRosWRegister - register a `TSROSW`, Rosenbrock W scheme by providing the entries in the Butcher tableau and optionally embedded approximations and interpolation 701e27a552bSJed Brown 702e27a552bSJed Brown Not Collective, but the same schemes should be registered on all processes on which they will be used 703e27a552bSJed Brown 704e27a552bSJed Brown Input Parameters: 705e27a552bSJed Brown + name - identifier for method 706e27a552bSJed Brown . order - approximation order of method 707e27a552bSJed Brown . s - number of stages, this is the dimension of the matrices below 70861692a83SJed Brown . A - Table of propagated stage coefficients (dimension s*s, row-major), strictly lower triangular 70961692a83SJed Brown . Gamma - Table of coefficients in implicit stage equations (dimension s*s, row-major), lower triangular with nonzero diagonal 710fe7e6d57SJed Brown . b - Step completion table (dimension s) 7110298fd71SBarry Smith . bembed - Step completion table for a scheme of order one less (dimension s, NULL if no embedded scheme is available) 712f4aed992SEmil Constantinescu . pinterp - Order of the interpolation scheme, equal to the number of columns of binterpt 71342faf41dSJed Brown - binterpt - Coefficients of the interpolation formula (dimension s*pinterp) 714e27a552bSJed Brown 715e27a552bSJed Brown Level: advanced 716e27a552bSJed Brown 717bcf0153eSBarry Smith Note: 718bcf0153eSBarry Smith Several Rosenbrock W methods are provided, this function is only needed to create new methods. 719bcf0153eSBarry Smith 7201cc06b55SBarry Smith .seealso: [](ch_ts), `TSROSW` 721e27a552bSJed Brown @*/ 722d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRosWRegister(TSRosWType name, PetscInt order, PetscInt s, const PetscReal A[], const PetscReal Gamma[], const PetscReal b[], const PetscReal bembed[], PetscInt pinterp, const PetscReal binterpt[]) 723d71ae5a4SJacob Faibussowitsch { 72461692a83SJed Brown RosWTableauLink link; 72561692a83SJed Brown RosWTableau t; 72661692a83SJed Brown PetscInt i, j, k; 72761692a83SJed Brown PetscScalar *GammaInv; 728e27a552bSJed Brown 729e27a552bSJed Brown PetscFunctionBegin; 7304f572ea9SToby Isaac PetscAssertPointer(name, 1); 7314f572ea9SToby Isaac PetscAssertPointer(A, 4); 7324f572ea9SToby Isaac PetscAssertPointer(Gamma, 5); 7334f572ea9SToby Isaac PetscAssertPointer(b, 6); 7344f572ea9SToby Isaac if (bembed) PetscAssertPointer(bembed, 7); 735fe7e6d57SJed Brown 7369566063dSJacob Faibussowitsch PetscCall(TSRosWInitializePackage()); 7379566063dSJacob Faibussowitsch PetscCall(PetscNew(&link)); 738e27a552bSJed Brown t = &link->tab; 7399566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(name, &t->name)); 740e27a552bSJed Brown t->order = order; 741e27a552bSJed Brown t->s = s; 7429566063dSJacob Faibussowitsch PetscCall(PetscMalloc5(s * s, &t->A, s * s, &t->Gamma, s, &t->b, s, &t->ASum, s, &t->GammaSum)); 7439566063dSJacob Faibussowitsch PetscCall(PetscMalloc5(s * s, &t->At, s, &t->bt, s * s, &t->GammaInv, s, &t->GammaZeroDiag, s * s, &t->GammaExplicitCorr)); 7449566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(t->A, A, s * s)); 7459566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(t->Gamma, Gamma, s * s)); 7469566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(t->GammaExplicitCorr, Gamma, s * s)); 7479566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(t->b, b, s)); 748fe7e6d57SJed Brown if (bembed) { 7499566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(s, &t->bembed, s, &t->bembedt)); 7509566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(t->bembed, bembed, s)); 751fe7e6d57SJed Brown } 75261692a83SJed Brown for (i = 0; i < s; i++) { 75361692a83SJed Brown t->ASum[i] = 0; 75461692a83SJed Brown t->GammaSum[i] = 0; 75561692a83SJed Brown for (j = 0; j < s; j++) { 75661692a83SJed Brown t->ASum[i] += A[i * s + j]; 757fe7e6d57SJed Brown t->GammaSum[i] += Gamma[i * s + j]; 75861692a83SJed Brown } 75961692a83SJed Brown } 7609566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(s * s, &GammaInv)); /* Need to use Scalar for inverse, then convert back to Real */ 76161692a83SJed Brown for (i = 0; i < s * s; i++) GammaInv[i] = Gamma[i]; 762fd96d5b0SEmil Constantinescu for (i = 0; i < s; i++) { 763fd96d5b0SEmil Constantinescu if (Gamma[i * s + i] == 0.0) { 764fd96d5b0SEmil Constantinescu GammaInv[i * s + i] = 1.0; 765c17803e7SJed Brown t->GammaZeroDiag[i] = PETSC_TRUE; 766fd96d5b0SEmil Constantinescu } else { 767c17803e7SJed Brown t->GammaZeroDiag[i] = PETSC_FALSE; 768fd96d5b0SEmil Constantinescu } 769fd96d5b0SEmil Constantinescu } 770fd96d5b0SEmil Constantinescu 77161692a83SJed Brown switch (s) { 772d71ae5a4SJacob Faibussowitsch case 1: 773d71ae5a4SJacob Faibussowitsch GammaInv[0] = 1. / GammaInv[0]; 774d71ae5a4SJacob Faibussowitsch break; 775d71ae5a4SJacob Faibussowitsch case 2: 776d71ae5a4SJacob Faibussowitsch PetscCall(PetscKernel_A_gets_inverse_A_2(GammaInv, 0, PETSC_FALSE, NULL)); 777d71ae5a4SJacob Faibussowitsch break; 778d71ae5a4SJacob Faibussowitsch case 3: 779d71ae5a4SJacob Faibussowitsch PetscCall(PetscKernel_A_gets_inverse_A_3(GammaInv, 0, PETSC_FALSE, NULL)); 780d71ae5a4SJacob Faibussowitsch break; 781d71ae5a4SJacob Faibussowitsch case 4: 782d71ae5a4SJacob Faibussowitsch PetscCall(PetscKernel_A_gets_inverse_A_4(GammaInv, 0, PETSC_FALSE, NULL)); 783d71ae5a4SJacob Faibussowitsch break; 78461692a83SJed Brown case 5: { 78561692a83SJed Brown PetscInt ipvt5[5]; 78661692a83SJed Brown MatScalar work5[5 * 5]; 7879371c9d4SSatish Balay PetscCall(PetscKernel_A_gets_inverse_A_5(GammaInv, ipvt5, work5, 0, PETSC_FALSE, NULL)); 7889371c9d4SSatish Balay break; 78961692a83SJed Brown } 790d71ae5a4SJacob Faibussowitsch case 6: 791d71ae5a4SJacob Faibussowitsch PetscCall(PetscKernel_A_gets_inverse_A_6(GammaInv, 0, PETSC_FALSE, NULL)); 792d71ae5a4SJacob Faibussowitsch break; 793d71ae5a4SJacob Faibussowitsch case 7: 794d71ae5a4SJacob Faibussowitsch PetscCall(PetscKernel_A_gets_inverse_A_7(GammaInv, 0, PETSC_FALSE, NULL)); 795d71ae5a4SJacob Faibussowitsch break; 796d71ae5a4SJacob Faibussowitsch default: 797d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Not implemented for %" PetscInt_FMT " stages", s); 79861692a83SJed Brown } 79961692a83SJed Brown for (i = 0; i < s * s; i++) t->GammaInv[i] = PetscRealPart(GammaInv[i]); 8009566063dSJacob Faibussowitsch PetscCall(PetscFree(GammaInv)); 80143b21953SEmil Constantinescu 80243b21953SEmil Constantinescu for (i = 0; i < s; i++) { 80343b21953SEmil Constantinescu for (k = 0; k < i + 1; k++) { 80443b21953SEmil Constantinescu t->GammaExplicitCorr[i * s + k] = (t->GammaExplicitCorr[i * s + k]) * (t->GammaInv[k * s + k]); 805ad540459SPierre Jolivet for (j = k + 1; j < i + 1; j++) t->GammaExplicitCorr[i * s + k] += (t->GammaExplicitCorr[i * s + j]) * (t->GammaInv[j * s + k]); 80643b21953SEmil Constantinescu } 80743b21953SEmil Constantinescu } 80843b21953SEmil Constantinescu 80961692a83SJed Brown for (i = 0; i < s; i++) { 81061692a83SJed Brown for (j = 0; j < s; j++) { 81161692a83SJed Brown t->At[i * s + j] = 0; 812ad540459SPierre Jolivet for (k = 0; k < s; k++) t->At[i * s + j] += t->A[i * s + k] * t->GammaInv[k * s + j]; 81361692a83SJed Brown } 81461692a83SJed Brown t->bt[i] = 0; 815ad540459SPierre Jolivet for (j = 0; j < s; j++) t->bt[i] += t->b[j] * t->GammaInv[j * s + i]; 816fe7e6d57SJed Brown if (bembed) { 817fe7e6d57SJed Brown t->bembedt[i] = 0; 818ad540459SPierre Jolivet for (j = 0; j < s; j++) t->bembedt[i] += t->bembed[j] * t->GammaInv[j * s + i]; 819fe7e6d57SJed Brown } 82061692a83SJed Brown } 8218d59e960SJed Brown t->ccfl = 1.0; /* Fix this */ 8228d59e960SJed Brown 823f4aed992SEmil Constantinescu t->pinterp = pinterp; 8249566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(s * pinterp, &t->binterpt)); 8259566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(t->binterpt, binterpt, s * pinterp)); 82661692a83SJed Brown link->next = RosWTableauList; 82761692a83SJed Brown RosWTableauList = link; 8283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 829e27a552bSJed Brown } 830e27a552bSJed Brown 83142faf41dSJed Brown /*@C 832fd292e60Sprj- TSRosWRegisterRos4 - register a fourth order Rosenbrock scheme by providing parameter choices 83342faf41dSJed Brown 83442faf41dSJed Brown Not Collective, but the same schemes should be registered on all processes on which they will be used 83542faf41dSJed Brown 83642faf41dSJed Brown Input Parameters: 83742faf41dSJed Brown + name - identifier for method 83842faf41dSJed Brown . gamma - leading coefficient (diagonal entry) 83942faf41dSJed Brown . a2 - design parameter, see Table 7.2 of Hairer&Wanner 84042faf41dSJed Brown . a3 - design parameter or PETSC_DEFAULT to satisfy one of the order five conditions (Eq 7.22) 84142faf41dSJed Brown . b3 - design parameter, see Table 7.2 of Hairer&Wanner 842a2b725a8SWilliam Gropp - e4 - design parameter for embedded method, see coefficient E4 in ros4.f code from Hairer 84342faf41dSJed Brown 844bcf0153eSBarry Smith Level: developer 845bcf0153eSBarry Smith 84642faf41dSJed Brown Notes: 84742faf41dSJed Brown This routine encodes the design of fourth order Rosenbrock methods as described in Hairer and Wanner volume 2. 84842faf41dSJed Brown It is used here to implement several methods from the book and can be used to experiment with new methods. 84942faf41dSJed Brown It was written this way instead of by copying coefficients in order to provide better than double precision satisfaction of the order conditions. 85042faf41dSJed Brown 8511cc06b55SBarry Smith .seealso: [](ch_ts), `TSRosW`, `TSRosWRegister()` 85242faf41dSJed Brown @*/ 853d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRosWRegisterRos4(TSRosWType name, PetscReal gamma, PetscReal a2, PetscReal a3, PetscReal b3, PetscReal e4) 854d71ae5a4SJacob Faibussowitsch { 85542faf41dSJed Brown /* Declare numeric constants so they can be quad precision without being truncated at double */ 8569371c9d4SSatish Balay const PetscReal one = 1, two = 2, three = 3, four = 4, five = 5, six = 6, eight = 8, twelve = 12, twenty = 20, twentyfour = 24, p32 = one / six - gamma + gamma * gamma, p42 = one / eight - gamma / three, p43 = one / twelve - gamma / three, p44 = one / twentyfour - gamma / two + three / two * gamma * gamma - gamma * gamma * gamma, p56 = one / twenty - gamma / four; 85742faf41dSJed Brown PetscReal a4, a32, a42, a43, b1, b2, b4, beta2p, beta3p, beta4p, beta32, beta42, beta43, beta32beta2p, beta4jbetajp; 85842faf41dSJed Brown PetscReal A[4][4], Gamma[4][4], b[4], bm[4]; 85942faf41dSJed Brown PetscScalar M[3][3], rhs[3]; 86042faf41dSJed Brown 86142faf41dSJed Brown PetscFunctionBegin; 86242faf41dSJed Brown /* Step 1: choose Gamma (input) */ 86342faf41dSJed Brown /* Step 2: choose a2,a3,a4; b1,b2,b3,b4 to satisfy order conditions */ 86413bcc0bdSJacob Faibussowitsch if (a3 == (PetscReal)PETSC_DEFAULT) a3 = (one / five - a2 / four) / (one / four - a2 / three); /* Eq 7.22 */ 86542faf41dSJed Brown a4 = a3; /* consequence of 7.20 */ 86642faf41dSJed Brown 86742faf41dSJed Brown /* Solve order conditions 7.15a, 7.15c, 7.15e */ 8689371c9d4SSatish Balay M[0][0] = one; 8699371c9d4SSatish Balay M[0][1] = one; 8709371c9d4SSatish Balay M[0][2] = one; /* 7.15a */ 8719371c9d4SSatish Balay M[1][0] = 0.0; 8729371c9d4SSatish Balay M[1][1] = a2 * a2; 8739371c9d4SSatish Balay M[1][2] = a4 * a4; /* 7.15c */ 8749371c9d4SSatish Balay M[2][0] = 0.0; 8759371c9d4SSatish Balay M[2][1] = a2 * a2 * a2; 8769371c9d4SSatish Balay M[2][2] = a4 * a4 * a4; /* 7.15e */ 87742faf41dSJed Brown rhs[0] = one - b3; 87842faf41dSJed Brown rhs[1] = one / three - a3 * a3 * b3; 87942faf41dSJed Brown rhs[2] = one / four - a3 * a3 * a3 * b3; 8809566063dSJacob Faibussowitsch PetscCall(PetscKernel_A_gets_inverse_A_3(&M[0][0], 0, PETSC_FALSE, NULL)); 88142faf41dSJed Brown b1 = PetscRealPart(M[0][0] * rhs[0] + M[0][1] * rhs[1] + M[0][2] * rhs[2]); 88242faf41dSJed Brown b2 = PetscRealPart(M[1][0] * rhs[0] + M[1][1] * rhs[1] + M[1][2] * rhs[2]); 88342faf41dSJed Brown b4 = PetscRealPart(M[2][0] * rhs[0] + M[2][1] * rhs[1] + M[2][2] * rhs[2]); 88442faf41dSJed Brown 88542faf41dSJed Brown /* Step 3 */ 88642faf41dSJed Brown beta43 = (p56 - a2 * p43) / (b4 * a3 * a3 * (a3 - a2)); /* 7.21 */ 88742faf41dSJed Brown beta32beta2p = p44 / (b4 * beta43); /* 7.15h */ 88842faf41dSJed Brown beta4jbetajp = (p32 - b3 * beta32beta2p) / b4; 8899371c9d4SSatish Balay M[0][0] = b2; 8909371c9d4SSatish Balay M[0][1] = b3; 8919371c9d4SSatish Balay M[0][2] = b4; 8929371c9d4SSatish Balay M[1][0] = a4 * a4 * beta32beta2p - a3 * a3 * beta4jbetajp; 8939371c9d4SSatish Balay M[1][1] = a2 * a2 * beta4jbetajp; 8949371c9d4SSatish Balay M[1][2] = -a2 * a2 * beta32beta2p; 8959371c9d4SSatish Balay M[2][0] = b4 * beta43 * a3 * a3 - p43; 8969371c9d4SSatish Balay M[2][1] = -b4 * beta43 * a2 * a2; 8979371c9d4SSatish Balay M[2][2] = 0; 8989371c9d4SSatish Balay rhs[0] = one / two - gamma; 8999371c9d4SSatish Balay rhs[1] = 0; 9009371c9d4SSatish Balay rhs[2] = -a2 * a2 * p32; 9019566063dSJacob Faibussowitsch PetscCall(PetscKernel_A_gets_inverse_A_3(&M[0][0], 0, PETSC_FALSE, NULL)); 90242faf41dSJed Brown beta2p = PetscRealPart(M[0][0] * rhs[0] + M[0][1] * rhs[1] + M[0][2] * rhs[2]); 90342faf41dSJed Brown beta3p = PetscRealPart(M[1][0] * rhs[0] + M[1][1] * rhs[1] + M[1][2] * rhs[2]); 90442faf41dSJed Brown beta4p = PetscRealPart(M[2][0] * rhs[0] + M[2][1] * rhs[1] + M[2][2] * rhs[2]); 90542faf41dSJed Brown 90642faf41dSJed Brown /* Step 4: back-substitute */ 90742faf41dSJed Brown beta32 = beta32beta2p / beta2p; 90842faf41dSJed Brown beta42 = (beta4jbetajp - beta43 * beta3p) / beta2p; 90942faf41dSJed Brown 91042faf41dSJed Brown /* Step 5: 7.15f and 7.20, then 7.16 */ 91142faf41dSJed Brown a43 = 0; 91242faf41dSJed Brown a32 = p42 / (b3 * a3 * beta2p + b4 * a4 * beta2p); 91342faf41dSJed Brown a42 = a32; 91442faf41dSJed Brown 9159371c9d4SSatish Balay A[0][0] = 0; 9169371c9d4SSatish Balay A[0][1] = 0; 9179371c9d4SSatish Balay A[0][2] = 0; 9189371c9d4SSatish Balay A[0][3] = 0; 9199371c9d4SSatish Balay A[1][0] = a2; 9209371c9d4SSatish Balay A[1][1] = 0; 9219371c9d4SSatish Balay A[1][2] = 0; 9229371c9d4SSatish Balay A[1][3] = 0; 9239371c9d4SSatish Balay A[2][0] = a3 - a32; 9249371c9d4SSatish Balay A[2][1] = a32; 9259371c9d4SSatish Balay A[2][2] = 0; 9269371c9d4SSatish Balay A[2][3] = 0; 9279371c9d4SSatish Balay A[3][0] = a4 - a43 - a42; 9289371c9d4SSatish Balay A[3][1] = a42; 9299371c9d4SSatish Balay A[3][2] = a43; 9309371c9d4SSatish Balay A[3][3] = 0; 9319371c9d4SSatish Balay Gamma[0][0] = gamma; 9329371c9d4SSatish Balay Gamma[0][1] = 0; 9339371c9d4SSatish Balay Gamma[0][2] = 0; 9349371c9d4SSatish Balay Gamma[0][3] = 0; 9359371c9d4SSatish Balay Gamma[1][0] = beta2p - A[1][0]; 9369371c9d4SSatish Balay Gamma[1][1] = gamma; 9379371c9d4SSatish Balay Gamma[1][2] = 0; 9389371c9d4SSatish Balay Gamma[1][3] = 0; 9399371c9d4SSatish Balay Gamma[2][0] = beta3p - beta32 - A[2][0]; 9409371c9d4SSatish Balay Gamma[2][1] = beta32 - A[2][1]; 9419371c9d4SSatish Balay Gamma[2][2] = gamma; 9429371c9d4SSatish Balay Gamma[2][3] = 0; 9439371c9d4SSatish Balay Gamma[3][0] = beta4p - beta42 - beta43 - A[3][0]; 9449371c9d4SSatish Balay Gamma[3][1] = beta42 - A[3][1]; 9459371c9d4SSatish Balay Gamma[3][2] = beta43 - A[3][2]; 9469371c9d4SSatish Balay Gamma[3][3] = gamma; 9479371c9d4SSatish Balay b[0] = b1; 9489371c9d4SSatish Balay b[1] = b2; 9499371c9d4SSatish Balay b[2] = b3; 9509371c9d4SSatish Balay b[3] = b4; 95142faf41dSJed Brown 95242faf41dSJed Brown /* Construct embedded formula using given e4. We are solving Equation 7.18. */ 95342faf41dSJed Brown bm[3] = b[3] - e4 * gamma; /* using definition of E4 */ 95442faf41dSJed Brown bm[2] = (p32 - beta4jbetajp * bm[3]) / (beta32 * beta2p); /* fourth row of 7.18 */ 95542faf41dSJed Brown bm[1] = (one / two - gamma - beta3p * bm[2] - beta4p * bm[3]) / beta2p; /* second row */ 95642faf41dSJed Brown bm[0] = one - bm[1] - bm[2] - bm[3]; /* first row */ 95742faf41dSJed Brown 95842faf41dSJed Brown { 95942faf41dSJed Brown const PetscReal misfit = a2 * a2 * bm[1] + a3 * a3 * bm[2] + a4 * a4 * bm[3] - one / three; 9603c633725SBarry Smith PetscCheck(PetscAbs(misfit) <= PETSC_SMALL, PETSC_COMM_SELF, PETSC_ERR_SUP, "Assumptions violated, could not construct a third order embedded method"); 96142faf41dSJed Brown } 9629566063dSJacob Faibussowitsch PetscCall(TSRosWRegister(name, 4, 4, &A[0][0], &Gamma[0][0], b, bm, 0, NULL)); 9633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 96442faf41dSJed Brown } 96542faf41dSJed Brown 9661c3436cfSJed Brown /* 9671c3436cfSJed Brown The step completion formula is 9681c3436cfSJed Brown 9691c3436cfSJed Brown x1 = x0 + b^T Y 9701c3436cfSJed Brown 9711c3436cfSJed Brown where Y is the multi-vector of stages corrections. This function can be called before or after ts->vec_sol has been 9721c3436cfSJed Brown updated. Suppose we have a completion formula b and an embedded formula be of different order. We can write 9731c3436cfSJed Brown 9741c3436cfSJed Brown x1e = x0 + be^T Y 9751c3436cfSJed Brown = x1 - b^T Y + be^T Y 9761c3436cfSJed Brown = x1 + (be - b)^T Y 9771c3436cfSJed Brown 9781c3436cfSJed Brown so we can evaluate the method of different order even after the step has been optimistically completed. 9791c3436cfSJed Brown */ 980d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSEvaluateStep_RosW(TS ts, PetscInt order, Vec U, PetscBool *done) 981d71ae5a4SJacob Faibussowitsch { 9821c3436cfSJed Brown TS_RosW *ros = (TS_RosW *)ts->data; 9831c3436cfSJed Brown RosWTableau tab = ros->tableau; 9841c3436cfSJed Brown PetscScalar *w = ros->work; 9851c3436cfSJed Brown PetscInt i; 9861c3436cfSJed Brown 9871c3436cfSJed Brown PetscFunctionBegin; 9881c3436cfSJed Brown if (order == tab->order) { 989108c343cSJed Brown if (ros->status == TS_STEP_INCOMPLETE) { /* Use standard completion formula */ 9909566063dSJacob Faibussowitsch PetscCall(VecCopy(ts->vec_sol, U)); 991de19f811SJed Brown for (i = 0; i < tab->s; i++) w[i] = tab->bt[i]; 9929566063dSJacob Faibussowitsch PetscCall(VecMAXPY(U, tab->s, w, ros->Y)); 9939566063dSJacob Faibussowitsch } else PetscCall(VecCopy(ts->vec_sol, U)); 9941c3436cfSJed Brown if (done) *done = PETSC_TRUE; 9953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9961c3436cfSJed Brown } else if (order == tab->order - 1) { 9971c3436cfSJed Brown if (!tab->bembedt) goto unavailable; 998108c343cSJed Brown if (ros->status == TS_STEP_INCOMPLETE) { /* Use embedded completion formula */ 9999566063dSJacob Faibussowitsch PetscCall(VecCopy(ts->vec_sol, U)); 1000de19f811SJed Brown for (i = 0; i < tab->s; i++) w[i] = tab->bembedt[i]; 10019566063dSJacob Faibussowitsch PetscCall(VecMAXPY(U, tab->s, w, ros->Y)); 1002108c343cSJed Brown } else { /* Use rollback-and-recomplete formula (bembedt - bt) */ 1003108c343cSJed Brown for (i = 0; i < tab->s; i++) w[i] = tab->bembedt[i] - tab->bt[i]; 10049566063dSJacob Faibussowitsch PetscCall(VecCopy(ts->vec_sol, U)); 10059566063dSJacob Faibussowitsch PetscCall(VecMAXPY(U, tab->s, w, ros->Y)); 10061c3436cfSJed Brown } 10071c3436cfSJed Brown if (done) *done = PETSC_TRUE; 10083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 10091c3436cfSJed Brown } 10101c3436cfSJed Brown unavailable: 10111c3436cfSJed Brown if (done) *done = PETSC_FALSE; 10129371c9d4SSatish Balay else 10139371c9d4SSatish Balay SETERRQ(PetscObjectComm((PetscObject)ts), PETSC_ERR_SUP, "Rosenbrock-W '%s' of order %" PetscInt_FMT " cannot evaluate step at order %" PetscInt_FMT ". Consider using -ts_adapt_type none or a different method that has an embedded estimate.", tab->name, 10149371c9d4SSatish Balay tab->order, order); 10153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 10161c3436cfSJed Brown } 10171c3436cfSJed Brown 1018d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSStep_RosW(TS ts) 1019d71ae5a4SJacob Faibussowitsch { 102061692a83SJed Brown TS_RosW *ros = (TS_RosW *)ts->data; 102161692a83SJed Brown RosWTableau tab = ros->tableau; 1022e27a552bSJed Brown const PetscInt s = tab->s; 10231c3436cfSJed Brown const PetscReal *At = tab->At, *Gamma = tab->Gamma, *ASum = tab->ASum, *GammaInv = tab->GammaInv; 10240feba352SEmil Constantinescu const PetscReal *GammaExplicitCorr = tab->GammaExplicitCorr; 1025c17803e7SJed Brown const PetscBool *GammaZeroDiag = tab->GammaZeroDiag; 102661692a83SJed Brown PetscScalar *w = ros->work; 10277d4bf2deSEmil Constantinescu Vec *Y = ros->Y, Ydot = ros->Ydot, Zdot = ros->Zdot, Zstage = ros->Zstage; 1028e27a552bSJed Brown SNES snes; 10291c3436cfSJed Brown TSAdapt adapt; 1030fecfb714SLisandro Dalcin PetscInt i, j, its, lits; 1031be5899b3SLisandro Dalcin PetscInt rejections = 0; 1032b39943a6SLisandro Dalcin PetscBool stageok, accept = PETSC_TRUE; 1033b39943a6SLisandro Dalcin PetscReal next_time_step = ts->time_step; 1034f7f07198SBarry Smith PetscInt lag; 1035e27a552bSJed Brown 1036e27a552bSJed Brown PetscFunctionBegin; 103748a46eb9SPierre Jolivet if (!ts->steprollback) PetscCall(VecCopy(ts->vec_sol, ros->vec_sol_prev)); 1038e27a552bSJed Brown 1039b39943a6SLisandro Dalcin ros->status = TS_STEP_INCOMPLETE; 1040b39943a6SLisandro Dalcin while (!ts->reason && ros->status != TS_STEP_COMPLETE) { 10411c3436cfSJed Brown const PetscReal h = ts->time_step; 1042e27a552bSJed Brown for (i = 0; i < s; i++) { 10431c3436cfSJed Brown ros->stage_time = ts->ptime + h * ASum[i]; 10449566063dSJacob Faibussowitsch PetscCall(TSPreStage(ts, ros->stage_time)); 1045c17803e7SJed Brown if (GammaZeroDiag[i]) { 1046c17803e7SJed Brown ros->stage_explicit = PETSC_TRUE; 1047b296d7d5SJed Brown ros->scoeff = 1.; 1048c17803e7SJed Brown } else { 1049c17803e7SJed Brown ros->stage_explicit = PETSC_FALSE; 1050b296d7d5SJed Brown ros->scoeff = 1. / Gamma[i * s + i]; 1051fd96d5b0SEmil Constantinescu } 105261692a83SJed Brown 10539566063dSJacob Faibussowitsch PetscCall(VecCopy(ts->vec_sol, Zstage)); 1054de19f811SJed Brown for (j = 0; j < i; j++) w[j] = At[i * s + j]; 10559566063dSJacob Faibussowitsch PetscCall(VecMAXPY(Zstage, i, w, Y)); 105661692a83SJed Brown 105761692a83SJed Brown for (j = 0; j < i; j++) w[j] = 1. / h * GammaInv[i * s + j]; 10589566063dSJacob Faibussowitsch PetscCall(VecZeroEntries(Zdot)); 10599566063dSJacob Faibussowitsch PetscCall(VecMAXPY(Zdot, i, w, Y)); 106061692a83SJed Brown 1061e27a552bSJed Brown /* Initial guess taken from last stage */ 10629566063dSJacob Faibussowitsch PetscCall(VecZeroEntries(Y[i])); 106361692a83SJed Brown 10647d4bf2deSEmil Constantinescu if (!ros->stage_explicit) { 10659566063dSJacob Faibussowitsch PetscCall(TSGetSNES(ts, &snes)); 106661692a83SJed Brown if (!ros->recompute_jacobian && !i) { 10679566063dSJacob Faibussowitsch PetscCall(SNESGetLagJacobian(snes, &lag)); 10686aad120cSJose E. Roman if (lag == 1) { /* use did not set a nontrivial lag, so lag over all stages */ 10699566063dSJacob Faibussowitsch PetscCall(SNESSetLagJacobian(snes, -2)); /* Recompute the Jacobian on this solve, but not again for the rest of the stages */ 1070f7f07198SBarry Smith } 107161692a83SJed Brown } 10729566063dSJacob Faibussowitsch PetscCall(SNESSolve(snes, NULL, Y[i])); 10739371c9d4SSatish Balay if (!ros->recompute_jacobian && i == s - 1 && lag == 1) { PetscCall(SNESSetLagJacobian(snes, lag)); /* Set lag back to 1 so we know user did not set it */ } 10749566063dSJacob Faibussowitsch PetscCall(SNESGetIterationNumber(snes, &its)); 10759566063dSJacob Faibussowitsch PetscCall(SNESGetLinearSolveIterations(snes, &lits)); 10769371c9d4SSatish Balay ts->snes_its += its; 10779371c9d4SSatish Balay ts->ksp_its += lits; 10787d4bf2deSEmil Constantinescu } else { 10791ce71dffSSatish Balay Mat J, Jp; 10809566063dSJacob Faibussowitsch PetscCall(VecZeroEntries(Ydot)); /* Evaluate Y[i]=G(t,Ydot=0,Zstage) */ 10819566063dSJacob Faibussowitsch PetscCall(TSComputeIFunction(ts, ros->stage_time, Zstage, Ydot, Y[i], PETSC_FALSE)); 10829566063dSJacob Faibussowitsch PetscCall(VecScale(Y[i], -1.0)); 10839566063dSJacob Faibussowitsch PetscCall(VecAXPY(Y[i], -1.0, Zdot)); /*Y[i] = F(Zstage)-Zdot[=GammaInv*Y]*/ 10840feba352SEmil Constantinescu 10859566063dSJacob Faibussowitsch PetscCall(VecZeroEntries(Zstage)); /* Zstage = GammaExplicitCorr[i,j] * Y[j] */ 10860feba352SEmil Constantinescu for (j = 0; j < i; j++) w[j] = GammaExplicitCorr[i * s + j]; 10879566063dSJacob Faibussowitsch PetscCall(VecMAXPY(Zstage, i, w, Y)); 1088fecfb714SLisandro Dalcin 1089fecfb714SLisandro Dalcin /* Y[i] = Y[i] + Jac*Zstage[=Jac*GammaExplicitCorr[i,j] * Y[j]] */ 10909566063dSJacob Faibussowitsch PetscCall(TSGetIJacobian(ts, &J, &Jp, NULL, NULL)); 10919566063dSJacob Faibussowitsch PetscCall(TSComputeIJacobian(ts, ros->stage_time, ts->vec_sol, Ydot, 0, J, Jp, PETSC_FALSE)); 10929566063dSJacob Faibussowitsch PetscCall(MatMult(J, Zstage, Zdot)); 10939566063dSJacob Faibussowitsch PetscCall(VecAXPY(Y[i], -1.0, Zdot)); 10945ef26d82SJed Brown ts->ksp_its += 1; 1095fecfb714SLisandro Dalcin 10969566063dSJacob Faibussowitsch PetscCall(VecScale(Y[i], h)); 10977d4bf2deSEmil Constantinescu } 10989566063dSJacob Faibussowitsch PetscCall(TSPostStage(ts, ros->stage_time, i, Y)); 10999566063dSJacob Faibussowitsch PetscCall(TSGetAdapt(ts, &adapt)); 11009566063dSJacob Faibussowitsch PetscCall(TSAdaptCheckStage(adapt, ts, ros->stage_time, Y[i], &stageok)); 1101fecfb714SLisandro Dalcin if (!stageok) goto reject_step; 1102e27a552bSJed Brown } 1103e27a552bSJed Brown 1104b39943a6SLisandro Dalcin ros->status = TS_STEP_INCOMPLETE; 11059566063dSJacob Faibussowitsch PetscCall(TSEvaluateStep_RosW(ts, tab->order, ts->vec_sol, NULL)); 1106b39943a6SLisandro Dalcin ros->status = TS_STEP_PENDING; 11079566063dSJacob Faibussowitsch PetscCall(TSGetAdapt(ts, &adapt)); 11089566063dSJacob Faibussowitsch PetscCall(TSAdaptCandidatesClear(adapt)); 11099566063dSJacob Faibussowitsch PetscCall(TSAdaptCandidateAdd(adapt, tab->name, tab->order, 1, tab->ccfl, (PetscReal)tab->s, PETSC_TRUE)); 11109566063dSJacob Faibussowitsch PetscCall(TSAdaptChoose(adapt, ts, ts->time_step, NULL, &next_time_step, &accept)); 1111b39943a6SLisandro Dalcin ros->status = accept ? TS_STEP_COMPLETE : TS_STEP_INCOMPLETE; 1112b39943a6SLisandro Dalcin if (!accept) { /* Roll back the current step */ 1113c61711c8SStefano Zampini PetscCall(VecCopy(ts->vec_sol0, ts->vec_sol)); 1114be5899b3SLisandro Dalcin ts->time_step = next_time_step; 1115be5899b3SLisandro Dalcin goto reject_step; 1116b39943a6SLisandro Dalcin } 1117b39943a6SLisandro Dalcin 1118e27a552bSJed Brown ts->ptime += ts->time_step; 1119cdbf8f93SLisandro Dalcin ts->time_step = next_time_step; 11201c3436cfSJed Brown break; 1121b39943a6SLisandro Dalcin 1122b39943a6SLisandro Dalcin reject_step: 11239371c9d4SSatish Balay ts->reject++; 11249371c9d4SSatish Balay accept = PETSC_FALSE; 1125be5899b3SLisandro Dalcin if (!ts->reason && ++rejections > ts->max_reject && ts->max_reject >= 0) { 1126b39943a6SLisandro Dalcin ts->reason = TS_DIVERGED_STEP_REJECTED; 112763a3b9bcSJacob Faibussowitsch PetscCall(PetscInfo(ts, "Step=%" PetscInt_FMT ", step rejections %" PetscInt_FMT " greater than current TS allowed, stopping solve\n", ts->steps, rejections)); 11281c3436cfSJed Brown } 11291c3436cfSJed Brown } 11303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1131e27a552bSJed Brown } 1132e27a552bSJed Brown 1133d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSInterpolate_RosW(TS ts, PetscReal itime, Vec U) 1134d71ae5a4SJacob Faibussowitsch { 113561692a83SJed Brown TS_RosW *ros = (TS_RosW *)ts->data; 1136f4aed992SEmil Constantinescu PetscInt s = ros->tableau->s, pinterp = ros->tableau->pinterp, i, j; 1137f4aed992SEmil Constantinescu PetscReal h; 1138f4aed992SEmil Constantinescu PetscReal tt, t; 1139f4aed992SEmil Constantinescu PetscScalar *bt; 1140f4aed992SEmil Constantinescu const PetscReal *Bt = ros->tableau->binterpt; 1141f4aed992SEmil Constantinescu const PetscReal *GammaInv = ros->tableau->GammaInv; 1142f4aed992SEmil Constantinescu PetscScalar *w = ros->work; 1143f4aed992SEmil Constantinescu Vec *Y = ros->Y; 1144e27a552bSJed Brown 1145e27a552bSJed Brown PetscFunctionBegin; 11463c633725SBarry Smith PetscCheck(Bt, PetscObjectComm((PetscObject)ts), PETSC_ERR_SUP, "TSRosW %s does not have an interpolation formula", ros->tableau->name); 1147f4aed992SEmil Constantinescu 1148f4aed992SEmil Constantinescu switch (ros->status) { 1149f4aed992SEmil Constantinescu case TS_STEP_INCOMPLETE: 1150f4aed992SEmil Constantinescu case TS_STEP_PENDING: 1151f4aed992SEmil Constantinescu h = ts->time_step; 1152f4aed992SEmil Constantinescu t = (itime - ts->ptime) / h; 1153f4aed992SEmil Constantinescu break; 1154f4aed992SEmil Constantinescu case TS_STEP_COMPLETE: 1155be5899b3SLisandro Dalcin h = ts->ptime - ts->ptime_prev; 1156f4aed992SEmil Constantinescu t = (itime - ts->ptime) / h + 1; /* In the interval [0,1] */ 1157f4aed992SEmil Constantinescu break; 1158d71ae5a4SJacob Faibussowitsch default: 1159d71ae5a4SJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)ts), PETSC_ERR_PLIB, "Invalid TSStepStatus"); 1160f4aed992SEmil Constantinescu } 11619566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(s, &bt)); 1162f4aed992SEmil Constantinescu for (i = 0; i < s; i++) bt[i] = 0; 1163f4aed992SEmil Constantinescu for (j = 0, tt = t; j < pinterp; j++, tt *= t) { 1164ad540459SPierre Jolivet for (i = 0; i < s; i++) bt[i] += Bt[i * pinterp + j] * tt; 1165f4aed992SEmil Constantinescu } 1166f4aed992SEmil Constantinescu 1167f4aed992SEmil Constantinescu /* y(t+tt*h) = y(t) + Sum bt(tt) * GammaInv * Ydot */ 1168f9c1d6abSBarry Smith /* U <- 0*/ 11699566063dSJacob Faibussowitsch PetscCall(VecZeroEntries(U)); 1170f9c1d6abSBarry Smith /* U <- Sum bt_i * GammaInv(i,1:i) * Y(1:i) */ 11713ca35412SEmil Constantinescu for (j = 0; j < s; j++) w[j] = 0; 11723ca35412SEmil Constantinescu for (j = 0; j < s; j++) { 1173ad540459SPierre Jolivet for (i = j; i < s; i++) w[j] += bt[i] * GammaInv[i * s + j]; 11743ca35412SEmil Constantinescu } 11759566063dSJacob Faibussowitsch PetscCall(VecMAXPY(U, i, w, Y)); 1176be5899b3SLisandro Dalcin /* U <- y(t) + U */ 11779566063dSJacob Faibussowitsch PetscCall(VecAXPY(U, 1, ros->vec_sol_prev)); 1178f4aed992SEmil Constantinescu 11799566063dSJacob Faibussowitsch PetscCall(PetscFree(bt)); 11803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1181e27a552bSJed Brown } 1182e27a552bSJed Brown 1183e27a552bSJed Brown /*------------------------------------------------------------*/ 1184b39943a6SLisandro Dalcin 1185d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSRosWTableauReset(TS ts) 1186d71ae5a4SJacob Faibussowitsch { 1187b39943a6SLisandro Dalcin TS_RosW *ros = (TS_RosW *)ts->data; 1188b39943a6SLisandro Dalcin RosWTableau tab = ros->tableau; 1189b39943a6SLisandro Dalcin 1190b39943a6SLisandro Dalcin PetscFunctionBegin; 11913ba16761SJacob Faibussowitsch if (!tab) PetscFunctionReturn(PETSC_SUCCESS); 11929566063dSJacob Faibussowitsch PetscCall(VecDestroyVecs(tab->s, &ros->Y)); 11939566063dSJacob Faibussowitsch PetscCall(PetscFree(ros->work)); 11943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1195b39943a6SLisandro Dalcin } 1196b39943a6SLisandro Dalcin 1197d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSReset_RosW(TS ts) 1198d71ae5a4SJacob Faibussowitsch { 119961692a83SJed Brown TS_RosW *ros = (TS_RosW *)ts->data; 1200e27a552bSJed Brown 1201e27a552bSJed Brown PetscFunctionBegin; 12029566063dSJacob Faibussowitsch PetscCall(TSRosWTableauReset(ts)); 12039566063dSJacob Faibussowitsch PetscCall(VecDestroy(&ros->Ydot)); 12049566063dSJacob Faibussowitsch PetscCall(VecDestroy(&ros->Ystage)); 12059566063dSJacob Faibussowitsch PetscCall(VecDestroy(&ros->Zdot)); 12069566063dSJacob Faibussowitsch PetscCall(VecDestroy(&ros->Zstage)); 12079566063dSJacob Faibussowitsch PetscCall(VecDestroy(&ros->vec_sol_prev)); 12083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1209e27a552bSJed Brown } 1210e27a552bSJed Brown 1211d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSRosWGetVecs(TS ts, DM dm, Vec *Ydot, Vec *Zdot, Vec *Ystage, Vec *Zstage) 1212d71ae5a4SJacob Faibussowitsch { 1213d5e6173cSPeter Brune TS_RosW *rw = (TS_RosW *)ts->data; 1214d5e6173cSPeter Brune 1215d5e6173cSPeter Brune PetscFunctionBegin; 1216d5e6173cSPeter Brune if (Ydot) { 1217d5e6173cSPeter Brune if (dm && dm != ts->dm) { 12189566063dSJacob Faibussowitsch PetscCall(DMGetNamedGlobalVector(dm, "TSRosW_Ydot", Ydot)); 1219d5e6173cSPeter Brune } else *Ydot = rw->Ydot; 1220d5e6173cSPeter Brune } 1221d5e6173cSPeter Brune if (Zdot) { 1222d5e6173cSPeter Brune if (dm && dm != ts->dm) { 12239566063dSJacob Faibussowitsch PetscCall(DMGetNamedGlobalVector(dm, "TSRosW_Zdot", Zdot)); 1224d5e6173cSPeter Brune } else *Zdot = rw->Zdot; 1225d5e6173cSPeter Brune } 1226d5e6173cSPeter Brune if (Ystage) { 1227d5e6173cSPeter Brune if (dm && dm != ts->dm) { 12289566063dSJacob Faibussowitsch PetscCall(DMGetNamedGlobalVector(dm, "TSRosW_Ystage", Ystage)); 1229d5e6173cSPeter Brune } else *Ystage = rw->Ystage; 1230d5e6173cSPeter Brune } 1231d5e6173cSPeter Brune if (Zstage) { 1232d5e6173cSPeter Brune if (dm && dm != ts->dm) { 12339566063dSJacob Faibussowitsch PetscCall(DMGetNamedGlobalVector(dm, "TSRosW_Zstage", Zstage)); 1234d5e6173cSPeter Brune } else *Zstage = rw->Zstage; 1235d5e6173cSPeter Brune } 12363ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1237d5e6173cSPeter Brune } 1238d5e6173cSPeter Brune 1239d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSRosWRestoreVecs(TS ts, DM dm, Vec *Ydot, Vec *Zdot, Vec *Ystage, Vec *Zstage) 1240d71ae5a4SJacob Faibussowitsch { 1241d5e6173cSPeter Brune PetscFunctionBegin; 1242d5e6173cSPeter Brune if (Ydot) { 124348a46eb9SPierre Jolivet if (dm && dm != ts->dm) PetscCall(DMRestoreNamedGlobalVector(dm, "TSRosW_Ydot", Ydot)); 1244d5e6173cSPeter Brune } 1245d5e6173cSPeter Brune if (Zdot) { 124648a46eb9SPierre Jolivet if (dm && dm != ts->dm) PetscCall(DMRestoreNamedGlobalVector(dm, "TSRosW_Zdot", Zdot)); 1247d5e6173cSPeter Brune } 1248d5e6173cSPeter Brune if (Ystage) { 124948a46eb9SPierre Jolivet if (dm && dm != ts->dm) PetscCall(DMRestoreNamedGlobalVector(dm, "TSRosW_Ystage", Ystage)); 1250d5e6173cSPeter Brune } 1251d5e6173cSPeter Brune if (Zstage) { 125248a46eb9SPierre Jolivet if (dm && dm != ts->dm) PetscCall(DMRestoreNamedGlobalVector(dm, "TSRosW_Zstage", Zstage)); 1253d5e6173cSPeter Brune } 12543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1255d5e6173cSPeter Brune } 1256d5e6173cSPeter Brune 1257d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMCoarsenHook_TSRosW(DM fine, DM coarse, void *ctx) 1258d71ae5a4SJacob Faibussowitsch { 1259d5e6173cSPeter Brune PetscFunctionBegin; 12603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1261d5e6173cSPeter Brune } 1262d5e6173cSPeter Brune 1263d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMRestrictHook_TSRosW(DM fine, Mat restrct, Vec rscale, Mat inject, DM coarse, void *ctx) 1264d71ae5a4SJacob Faibussowitsch { 1265d5e6173cSPeter Brune TS ts = (TS)ctx; 1266d5e6173cSPeter Brune Vec Ydot, Zdot, Ystage, Zstage; 1267d5e6173cSPeter Brune Vec Ydotc, Zdotc, Ystagec, Zstagec; 1268d5e6173cSPeter Brune 1269d5e6173cSPeter Brune PetscFunctionBegin; 12709566063dSJacob Faibussowitsch PetscCall(TSRosWGetVecs(ts, fine, &Ydot, &Ystage, &Zdot, &Zstage)); 12719566063dSJacob Faibussowitsch PetscCall(TSRosWGetVecs(ts, coarse, &Ydotc, &Ystagec, &Zdotc, &Zstagec)); 12729566063dSJacob Faibussowitsch PetscCall(MatRestrict(restrct, Ydot, Ydotc)); 12739566063dSJacob Faibussowitsch PetscCall(VecPointwiseMult(Ydotc, rscale, Ydotc)); 12749566063dSJacob Faibussowitsch PetscCall(MatRestrict(restrct, Ystage, Ystagec)); 12759566063dSJacob Faibussowitsch PetscCall(VecPointwiseMult(Ystagec, rscale, Ystagec)); 12769566063dSJacob Faibussowitsch PetscCall(MatRestrict(restrct, Zdot, Zdotc)); 12779566063dSJacob Faibussowitsch PetscCall(VecPointwiseMult(Zdotc, rscale, Zdotc)); 12789566063dSJacob Faibussowitsch PetscCall(MatRestrict(restrct, Zstage, Zstagec)); 12799566063dSJacob Faibussowitsch PetscCall(VecPointwiseMult(Zstagec, rscale, Zstagec)); 12809566063dSJacob Faibussowitsch PetscCall(TSRosWRestoreVecs(ts, fine, &Ydot, &Ystage, &Zdot, &Zstage)); 12819566063dSJacob Faibussowitsch PetscCall(TSRosWRestoreVecs(ts, coarse, &Ydotc, &Ystagec, &Zdotc, &Zstagec)); 12823ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1283d5e6173cSPeter Brune } 1284d5e6173cSPeter Brune 1285d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMSubDomainHook_TSRosW(DM fine, DM coarse, void *ctx) 1286d71ae5a4SJacob Faibussowitsch { 1287258e1594SPeter Brune PetscFunctionBegin; 12883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1289258e1594SPeter Brune } 1290258e1594SPeter Brune 1291d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMSubDomainRestrictHook_TSRosW(DM dm, VecScatter gscat, VecScatter lscat, DM subdm, void *ctx) 1292d71ae5a4SJacob Faibussowitsch { 1293258e1594SPeter Brune TS ts = (TS)ctx; 1294258e1594SPeter Brune Vec Ydot, Zdot, Ystage, Zstage; 1295258e1594SPeter Brune Vec Ydots, Zdots, Ystages, Zstages; 1296258e1594SPeter Brune 1297258e1594SPeter Brune PetscFunctionBegin; 12989566063dSJacob Faibussowitsch PetscCall(TSRosWGetVecs(ts, dm, &Ydot, &Ystage, &Zdot, &Zstage)); 12999566063dSJacob Faibussowitsch PetscCall(TSRosWGetVecs(ts, subdm, &Ydots, &Ystages, &Zdots, &Zstages)); 1300258e1594SPeter Brune 13019566063dSJacob Faibussowitsch PetscCall(VecScatterBegin(gscat, Ydot, Ydots, INSERT_VALUES, SCATTER_FORWARD)); 13029566063dSJacob Faibussowitsch PetscCall(VecScatterEnd(gscat, Ydot, Ydots, INSERT_VALUES, SCATTER_FORWARD)); 1303258e1594SPeter Brune 13049566063dSJacob Faibussowitsch PetscCall(VecScatterBegin(gscat, Ystage, Ystages, INSERT_VALUES, SCATTER_FORWARD)); 13059566063dSJacob Faibussowitsch PetscCall(VecScatterEnd(gscat, Ystage, Ystages, INSERT_VALUES, SCATTER_FORWARD)); 1306258e1594SPeter Brune 13079566063dSJacob Faibussowitsch PetscCall(VecScatterBegin(gscat, Zdot, Zdots, INSERT_VALUES, SCATTER_FORWARD)); 13089566063dSJacob Faibussowitsch PetscCall(VecScatterEnd(gscat, Zdot, Zdots, INSERT_VALUES, SCATTER_FORWARD)); 1309258e1594SPeter Brune 13109566063dSJacob Faibussowitsch PetscCall(VecScatterBegin(gscat, Zstage, Zstages, INSERT_VALUES, SCATTER_FORWARD)); 13119566063dSJacob Faibussowitsch PetscCall(VecScatterEnd(gscat, Zstage, Zstages, INSERT_VALUES, SCATTER_FORWARD)); 1312258e1594SPeter Brune 13139566063dSJacob Faibussowitsch PetscCall(TSRosWRestoreVecs(ts, dm, &Ydot, &Ystage, &Zdot, &Zstage)); 13149566063dSJacob Faibussowitsch PetscCall(TSRosWRestoreVecs(ts, subdm, &Ydots, &Ystages, &Zdots, &Zstages)); 13153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1316258e1594SPeter Brune } 1317258e1594SPeter Brune 1318d71ae5a4SJacob Faibussowitsch static PetscErrorCode SNESTSFormFunction_RosW(SNES snes, Vec U, Vec F, TS ts) 1319d71ae5a4SJacob Faibussowitsch { 132061692a83SJed Brown TS_RosW *ros = (TS_RosW *)ts->data; 1321d5e6173cSPeter Brune Vec Ydot, Zdot, Ystage, Zstage; 1322b296d7d5SJed Brown PetscReal shift = ros->scoeff / ts->time_step; 1323d5e6173cSPeter Brune DM dm, dmsave; 1324e27a552bSJed Brown 1325e27a552bSJed Brown PetscFunctionBegin; 13269566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 13279566063dSJacob Faibussowitsch PetscCall(TSRosWGetVecs(ts, dm, &Ydot, &Zdot, &Ystage, &Zstage)); 13289566063dSJacob Faibussowitsch PetscCall(VecWAXPY(Ydot, shift, U, Zdot)); /* Ydot = shift*U + Zdot */ 13299566063dSJacob Faibussowitsch PetscCall(VecWAXPY(Ystage, 1.0, U, Zstage)); /* Ystage = U + Zstage */ 1330d5e6173cSPeter Brune dmsave = ts->dm; 1331d5e6173cSPeter Brune ts->dm = dm; 13329566063dSJacob Faibussowitsch PetscCall(TSComputeIFunction(ts, ros->stage_time, Ystage, Ydot, F, PETSC_FALSE)); 1333d5e6173cSPeter Brune ts->dm = dmsave; 13349566063dSJacob Faibussowitsch PetscCall(TSRosWRestoreVecs(ts, dm, &Ydot, &Zdot, &Ystage, &Zstage)); 13353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1336e27a552bSJed Brown } 1337e27a552bSJed Brown 1338d71ae5a4SJacob Faibussowitsch static PetscErrorCode SNESTSFormJacobian_RosW(SNES snes, Vec U, Mat A, Mat B, TS ts) 1339d71ae5a4SJacob Faibussowitsch { 134061692a83SJed Brown TS_RosW *ros = (TS_RosW *)ts->data; 1341d5e6173cSPeter Brune Vec Ydot, Zdot, Ystage, Zstage; 1342b296d7d5SJed Brown PetscReal shift = ros->scoeff / ts->time_step; 1343d5e6173cSPeter Brune DM dm, dmsave; 1344e27a552bSJed Brown 1345e27a552bSJed Brown PetscFunctionBegin; 134661692a83SJed Brown /* ros->Ydot and ros->Ystage have already been computed in SNESTSFormFunction_RosW (SNES guarantees this) */ 13479566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 13489566063dSJacob Faibussowitsch PetscCall(TSRosWGetVecs(ts, dm, &Ydot, &Zdot, &Ystage, &Zstage)); 1349d5e6173cSPeter Brune dmsave = ts->dm; 1350d5e6173cSPeter Brune ts->dm = dm; 13519566063dSJacob Faibussowitsch PetscCall(TSComputeIJacobian(ts, ros->stage_time, Ystage, Ydot, shift, A, B, PETSC_TRUE)); 1352d5e6173cSPeter Brune ts->dm = dmsave; 13539566063dSJacob Faibussowitsch PetscCall(TSRosWRestoreVecs(ts, dm, &Ydot, &Zdot, &Ystage, &Zstage)); 13543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1355e27a552bSJed Brown } 1356e27a552bSJed Brown 1357d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSRosWTableauSetUp(TS ts) 1358d71ae5a4SJacob Faibussowitsch { 1359b39943a6SLisandro Dalcin TS_RosW *ros = (TS_RosW *)ts->data; 1360b39943a6SLisandro Dalcin RosWTableau tab = ros->tableau; 1361b39943a6SLisandro Dalcin 1362b39943a6SLisandro Dalcin PetscFunctionBegin; 13639566063dSJacob Faibussowitsch PetscCall(VecDuplicateVecs(ts->vec_sol, tab->s, &ros->Y)); 13649566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(tab->s, &ros->work)); 13653ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1366b39943a6SLisandro Dalcin } 1367b39943a6SLisandro Dalcin 1368d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSSetUp_RosW(TS ts) 1369d71ae5a4SJacob Faibussowitsch { 137061692a83SJed Brown TS_RosW *ros = (TS_RosW *)ts->data; 1371d5e6173cSPeter Brune DM dm; 1372b39943a6SLisandro Dalcin SNES snes; 13738434afd1SBarry Smith TSRHSJacobianFn *rhsjacobian; 1374e27a552bSJed Brown 1375e27a552bSJed Brown PetscFunctionBegin; 13769566063dSJacob Faibussowitsch PetscCall(TSRosWTableauSetUp(ts)); 13779566063dSJacob Faibussowitsch PetscCall(VecDuplicate(ts->vec_sol, &ros->Ydot)); 13789566063dSJacob Faibussowitsch PetscCall(VecDuplicate(ts->vec_sol, &ros->Ystage)); 13799566063dSJacob Faibussowitsch PetscCall(VecDuplicate(ts->vec_sol, &ros->Zdot)); 13809566063dSJacob Faibussowitsch PetscCall(VecDuplicate(ts->vec_sol, &ros->Zstage)); 13819566063dSJacob Faibussowitsch PetscCall(VecDuplicate(ts->vec_sol, &ros->vec_sol_prev)); 13829566063dSJacob Faibussowitsch PetscCall(TSGetDM(ts, &dm)); 13839566063dSJacob Faibussowitsch PetscCall(DMCoarsenHookAdd(dm, DMCoarsenHook_TSRosW, DMRestrictHook_TSRosW, ts)); 13849566063dSJacob Faibussowitsch PetscCall(DMSubDomainHookAdd(dm, DMSubDomainHook_TSRosW, DMSubDomainRestrictHook_TSRosW, ts)); 1385b39943a6SLisandro Dalcin /* Rosenbrock methods are linearly implicit, so set that unless the user has specifically asked for something else */ 13869566063dSJacob Faibussowitsch PetscCall(TSGetSNES(ts, &snes)); 138748a46eb9SPierre Jolivet if (!((PetscObject)snes)->type_name) PetscCall(SNESSetType(snes, SNESKSPONLY)); 13889566063dSJacob Faibussowitsch PetscCall(DMTSGetRHSJacobian(dm, &rhsjacobian, NULL)); 1389a3ab5968SHong Zhang if (rhsjacobian == TSComputeRHSJacobianConstant) { 1390a3ab5968SHong Zhang Mat Amat, Pmat; 1391a3ab5968SHong Zhang 1392a3ab5968SHong Zhang /* Set the SNES matrix to be different from the RHS matrix because there is no way to reconstruct shift*M-J */ 13939566063dSJacob Faibussowitsch PetscCall(SNESGetJacobian(snes, &Amat, &Pmat, NULL, NULL)); 1394a3ab5968SHong Zhang if (Amat && Amat == ts->Arhs) { 1395a3ab5968SHong Zhang if (Amat == Pmat) { 13969566063dSJacob Faibussowitsch PetscCall(MatDuplicate(ts->Arhs, MAT_COPY_VALUES, &Amat)); 13979566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, Amat, Amat, NULL, NULL)); 1398a3ab5968SHong Zhang } else { 13999566063dSJacob Faibussowitsch PetscCall(MatDuplicate(ts->Arhs, MAT_COPY_VALUES, &Amat)); 14009566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, Amat, NULL, NULL, NULL)); 1401a3ab5968SHong Zhang if (Pmat && Pmat == ts->Brhs) { 14029566063dSJacob Faibussowitsch PetscCall(MatDuplicate(ts->Brhs, MAT_COPY_VALUES, &Pmat)); 14039566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, NULL, Pmat, NULL, NULL)); 14049566063dSJacob Faibussowitsch PetscCall(MatDestroy(&Pmat)); 1405a3ab5968SHong Zhang } 1406a3ab5968SHong Zhang } 14079566063dSJacob Faibussowitsch PetscCall(MatDestroy(&Amat)); 1408a3ab5968SHong Zhang } 1409a3ab5968SHong Zhang } 14103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1411e27a552bSJed Brown } 1412e27a552bSJed Brown /*------------------------------------------------------------*/ 1413e27a552bSJed Brown 1414d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSSetFromOptions_RosW(TS ts, PetscOptionItems *PetscOptionsObject) 1415d71ae5a4SJacob Faibussowitsch { 141661692a83SJed Brown TS_RosW *ros = (TS_RosW *)ts->data; 1417b39943a6SLisandro Dalcin SNES snes; 1418e27a552bSJed Brown 1419e27a552bSJed Brown PetscFunctionBegin; 1420d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "RosW ODE solver options"); 1421e27a552bSJed Brown { 142261692a83SJed Brown RosWTableauLink link; 1423e27a552bSJed Brown PetscInt count, choice; 1424e27a552bSJed Brown PetscBool flg; 1425e27a552bSJed Brown const char **namelist; 142661692a83SJed Brown 1427fbccb6d4SPierre Jolivet for (link = RosWTableauList, count = 0; link; link = link->next, count++); 14289566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(count, (char ***)&namelist)); 142961692a83SJed Brown for (link = RosWTableauList, count = 0; link; link = link->next, count++) namelist[count] = link->tab.name; 14309566063dSJacob Faibussowitsch PetscCall(PetscOptionsEList("-ts_rosw_type", "Family of Rosenbrock-W method", "TSRosWSetType", (const char *const *)namelist, count, ros->tableau->name, &choice, &flg)); 14319566063dSJacob Faibussowitsch if (flg) PetscCall(TSRosWSetType(ts, namelist[choice])); 14329566063dSJacob Faibussowitsch PetscCall(PetscFree(namelist)); 143361692a83SJed Brown 14349566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-ts_rosw_recompute_jacobian", "Recompute the Jacobian at each stage", "TSRosWSetRecomputeJacobian", ros->recompute_jacobian, &ros->recompute_jacobian, NULL)); 1435b39943a6SLisandro Dalcin } 1436d0609cedSBarry Smith PetscOptionsHeadEnd(); 143761692a83SJed Brown /* Rosenbrock methods are linearly implicit, so set that unless the user has specifically asked for something else */ 14389566063dSJacob Faibussowitsch PetscCall(TSGetSNES(ts, &snes)); 143948a46eb9SPierre Jolivet if (!((PetscObject)snes)->type_name) PetscCall(SNESSetType(snes, SNESKSPONLY)); 14403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1441e27a552bSJed Brown } 1442e27a552bSJed Brown 1443d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSView_RosW(TS ts, PetscViewer viewer) 1444d71ae5a4SJacob Faibussowitsch { 144561692a83SJed Brown TS_RosW *ros = (TS_RosW *)ts->data; 1446e27a552bSJed Brown PetscBool iascii; 1447e27a552bSJed Brown 1448e27a552bSJed Brown PetscFunctionBegin; 14499566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 1450e27a552bSJed Brown if (iascii) { 14519c334d8fSLisandro Dalcin RosWTableau tab = ros->tableau; 145219fd82e9SBarry Smith TSRosWType rostype; 14539c334d8fSLisandro Dalcin char buf[512]; 1454e408995aSJed Brown PetscInt i; 1455e408995aSJed Brown PetscReal abscissa[512]; 14569566063dSJacob Faibussowitsch PetscCall(TSRosWGetType(ts, &rostype)); 14579566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Rosenbrock-W %s\n", rostype)); 14589566063dSJacob Faibussowitsch PetscCall(PetscFormatRealArray(buf, sizeof(buf), "% 8.6f", tab->s, tab->ASum)); 14599566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Abscissa of A = %s\n", buf)); 1460e408995aSJed Brown for (i = 0; i < tab->s; i++) abscissa[i] = tab->ASum[i] + tab->Gamma[i]; 14619566063dSJacob Faibussowitsch PetscCall(PetscFormatRealArray(buf, sizeof(buf), "% 8.6f", tab->s, abscissa)); 14629566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Abscissa of A+Gamma = %s\n", buf)); 1463e27a552bSJed Brown } 14643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1465e27a552bSJed Brown } 1466e27a552bSJed Brown 1467d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSLoad_RosW(TS ts, PetscViewer viewer) 1468d71ae5a4SJacob Faibussowitsch { 14699200755eSBarry Smith SNES snes; 14709c334d8fSLisandro Dalcin TSAdapt adapt; 14719200755eSBarry Smith 14729200755eSBarry Smith PetscFunctionBegin; 14739566063dSJacob Faibussowitsch PetscCall(TSGetAdapt(ts, &adapt)); 14749566063dSJacob Faibussowitsch PetscCall(TSAdaptLoad(adapt, viewer)); 14759566063dSJacob Faibussowitsch PetscCall(TSGetSNES(ts, &snes)); 14769566063dSJacob Faibussowitsch PetscCall(SNESLoad(snes, viewer)); 14779200755eSBarry Smith /* function and Jacobian context for SNES when used with TS is always ts object */ 14789566063dSJacob Faibussowitsch PetscCall(SNESSetFunction(snes, NULL, NULL, ts)); 14799566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, NULL, NULL, NULL, ts)); 14803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 14819200755eSBarry Smith } 14829200755eSBarry Smith 1483e27a552bSJed Brown /*@C 1484bcf0153eSBarry Smith TSRosWSetType - Set the type of Rosenbrock-W, `TSROSW`, scheme 1485e27a552bSJed Brown 148620f4b53cSBarry Smith Logically Collective 1487e27a552bSJed Brown 1488d8d19677SJose E. Roman Input Parameters: 1489e27a552bSJed Brown + ts - timestepping context 1490b92453a8SLisandro Dalcin - roswtype - type of Rosenbrock-W scheme 1491e27a552bSJed Brown 1492020d8f30SJed Brown Level: beginner 1493e27a552bSJed Brown 14941cc06b55SBarry Smith .seealso: [](ch_ts), `TSRosWGetType()`, `TSROSW`, `TSROSW2M`, `TSROSW2P`, `TSROSWRA3PW`, `TSROSWRA34PW2`, `TSROSWRODAS3`, `TSROSWSANDU3`, `TSROSWASSP3P3S1C`, `TSROSWLASSP3P4S2C`, `TSROSWLLSSP3P4S2C`, `TSROSWARK3` 1495e27a552bSJed Brown @*/ 1496d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRosWSetType(TS ts, TSRosWType roswtype) 1497d71ae5a4SJacob Faibussowitsch { 1498e27a552bSJed Brown PetscFunctionBegin; 1499e27a552bSJed Brown PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 15004f572ea9SToby Isaac PetscAssertPointer(roswtype, 2); 1501cac4c232SBarry Smith PetscTryMethod(ts, "TSRosWSetType_C", (TS, TSRosWType), (ts, roswtype)); 15023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1503e27a552bSJed Brown } 1504e27a552bSJed Brown 1505e27a552bSJed Brown /*@C 150661692a83SJed Brown TSRosWGetType - Get the type of Rosenbrock-W scheme 1507e27a552bSJed Brown 150820f4b53cSBarry Smith Logically Collective 1509e27a552bSJed Brown 1510e27a552bSJed Brown Input Parameter: 1511e27a552bSJed Brown . ts - timestepping context 1512e27a552bSJed Brown 1513e27a552bSJed Brown Output Parameter: 151461692a83SJed Brown . rostype - type of Rosenbrock-W scheme 1515e27a552bSJed Brown 1516e27a552bSJed Brown Level: intermediate 1517e27a552bSJed Brown 15181cc06b55SBarry Smith .seealso: [](ch_ts), `TSRosWType`, `TSRosWSetType()` 1519e27a552bSJed Brown @*/ 1520d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRosWGetType(TS ts, TSRosWType *rostype) 1521d71ae5a4SJacob Faibussowitsch { 1522e27a552bSJed Brown PetscFunctionBegin; 1523e27a552bSJed Brown PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 1524cac4c232SBarry Smith PetscUseMethod(ts, "TSRosWGetType_C", (TS, TSRosWType *), (ts, rostype)); 15253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1526e27a552bSJed Brown } 1527e27a552bSJed Brown 1528e27a552bSJed Brown /*@C 152961692a83SJed Brown TSRosWSetRecomputeJacobian - Set whether to recompute the Jacobian at each stage. The default is to update the Jacobian once per step. 1530e27a552bSJed Brown 153120f4b53cSBarry Smith Logically Collective 1532e27a552bSJed Brown 1533d8d19677SJose E. Roman Input Parameters: 1534e27a552bSJed Brown + ts - timestepping context 1535bcf0153eSBarry Smith - flg - `PETSC_TRUE` to recompute the Jacobian at each stage 1536e27a552bSJed Brown 1537e27a552bSJed Brown Level: intermediate 1538e27a552bSJed Brown 15391cc06b55SBarry Smith .seealso: [](ch_ts), `TSRosWType`, `TSRosWGetType()` 1540e27a552bSJed Brown @*/ 1541d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRosWSetRecomputeJacobian(TS ts, PetscBool flg) 1542d71ae5a4SJacob Faibussowitsch { 1543e27a552bSJed Brown PetscFunctionBegin; 1544e27a552bSJed Brown PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 1545cac4c232SBarry Smith PetscTryMethod(ts, "TSRosWSetRecomputeJacobian_C", (TS, PetscBool), (ts, flg)); 15463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1547e27a552bSJed Brown } 1548e27a552bSJed Brown 1549d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSRosWGetType_RosW(TS ts, TSRosWType *rostype) 1550d71ae5a4SJacob Faibussowitsch { 155161692a83SJed Brown TS_RosW *ros = (TS_RosW *)ts->data; 1552e27a552bSJed Brown 1553e27a552bSJed Brown PetscFunctionBegin; 155461692a83SJed Brown *rostype = ros->tableau->name; 15553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1556e27a552bSJed Brown } 1557ef20d060SBarry Smith 1558d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSRosWSetType_RosW(TS ts, TSRosWType rostype) 1559d71ae5a4SJacob Faibussowitsch { 156061692a83SJed Brown TS_RosW *ros = (TS_RosW *)ts->data; 1561e27a552bSJed Brown PetscBool match; 156261692a83SJed Brown RosWTableauLink link; 1563e27a552bSJed Brown 1564e27a552bSJed Brown PetscFunctionBegin; 156561692a83SJed Brown if (ros->tableau) { 15669566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(ros->tableau->name, rostype, &match)); 15673ba16761SJacob Faibussowitsch if (match) PetscFunctionReturn(PETSC_SUCCESS); 1568e27a552bSJed Brown } 156961692a83SJed Brown for (link = RosWTableauList; link; link = link->next) { 15709566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(link->tab.name, rostype, &match)); 1571e27a552bSJed Brown if (match) { 15729566063dSJacob Faibussowitsch if (ts->setupcalled) PetscCall(TSRosWTableauReset(ts)); 157361692a83SJed Brown ros->tableau = &link->tab; 15749566063dSJacob Faibussowitsch if (ts->setupcalled) PetscCall(TSRosWTableauSetUp(ts)); 15752ffb9264SLisandro Dalcin ts->default_adapt_type = ros->tableau->bembed ? TSADAPTBASIC : TSADAPTNONE; 15763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1577e27a552bSJed Brown } 1578e27a552bSJed Brown } 157998921bdaSJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_UNKNOWN_TYPE, "Could not find '%s'", rostype); 1580e27a552bSJed Brown } 158161692a83SJed Brown 1582d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSRosWSetRecomputeJacobian_RosW(TS ts, PetscBool flg) 1583d71ae5a4SJacob Faibussowitsch { 158461692a83SJed Brown TS_RosW *ros = (TS_RosW *)ts->data; 1585e27a552bSJed Brown 1586e27a552bSJed Brown PetscFunctionBegin; 158761692a83SJed Brown ros->recompute_jacobian = flg; 15883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1589e27a552bSJed Brown } 1590e27a552bSJed Brown 1591d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSDestroy_RosW(TS ts) 1592d71ae5a4SJacob Faibussowitsch { 1593b3a6b972SJed Brown PetscFunctionBegin; 15949566063dSJacob Faibussowitsch PetscCall(TSReset_RosW(ts)); 1595b3a6b972SJed Brown if (ts->dm) { 15969566063dSJacob Faibussowitsch PetscCall(DMCoarsenHookRemove(ts->dm, DMCoarsenHook_TSRosW, DMRestrictHook_TSRosW, ts)); 15979566063dSJacob Faibussowitsch PetscCall(DMSubDomainHookRemove(ts->dm, DMSubDomainHook_TSRosW, DMSubDomainRestrictHook_TSRosW, ts)); 1598b3a6b972SJed Brown } 15999566063dSJacob Faibussowitsch PetscCall(PetscFree(ts->data)); 16009566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSRosWGetType_C", NULL)); 16019566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSRosWSetType_C", NULL)); 16029566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSRosWSetRecomputeJacobian_C", NULL)); 16033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1604b3a6b972SJed Brown } 1605d5e6173cSPeter Brune 1606e27a552bSJed Brown /* ------------------------------------------------------------ */ 1607e27a552bSJed Brown /*MC 1608020d8f30SJed Brown TSROSW - ODE solver using Rosenbrock-W schemes 1609e27a552bSJed Brown 1610e27a552bSJed Brown These methods are intended for problems with well-separated time scales, especially when a slow scale is strongly 1611e27a552bSJed Brown nonlinear such that it is expensive to solve with a fully implicit method. The user should provide the stiff part 1612bcf0153eSBarry Smith of the equation using `TSSetIFunction()` and the non-stiff part with `TSSetRHSFunction()`. 1613bcf0153eSBarry Smith 1614bcf0153eSBarry Smith Level: beginner 1615e27a552bSJed Brown 1616e27a552bSJed Brown Notes: 161761692a83SJed Brown This method currently only works with autonomous ODE and DAE. 161861692a83SJed Brown 1619bcf0153eSBarry Smith Consider trying `TSARKIMEX` if the stiff part is strongly nonlinear. 1620d0685a90SJed Brown 16213d5a8a6aSBarry Smith Since this uses a single linear solve per time-step if you wish to lag the jacobian or preconditioner computation you must use also -snes_lag_jacobian_persists true or -snes_lag_jacobian_preconditioner true 16223d5a8a6aSBarry Smith 1623e94cfbe0SPatrick Sanan Developer Notes: 162461692a83SJed Brown Rosenbrock-W methods are typically specified for autonomous ODE 162561692a83SJed Brown 1626f9c1d6abSBarry Smith $ udot = f(u) 162761692a83SJed Brown 162861692a83SJed Brown by the stage equations 162961692a83SJed Brown 1630f9c1d6abSBarry Smith $ k_i = h f(u_0 + sum_j alpha_ij k_j) + h J sum_j gamma_ij k_j 163161692a83SJed Brown 163261692a83SJed Brown and step completion formula 163361692a83SJed Brown 1634f9c1d6abSBarry Smith $ u_1 = u_0 + sum_j b_j k_j 163561692a83SJed Brown 1636f9c1d6abSBarry Smith with step size h and coefficients alpha_ij, gamma_ij, and b_i. Implementing the method in this form would require f(u) 163761692a83SJed Brown and the Jacobian J to be available, in addition to the shifted matrix I - h gamma_ii J. Following Hairer and Wanner, 163861692a83SJed Brown we define new variables for the stage equations 163961692a83SJed Brown 164061692a83SJed Brown $ y_i = gamma_ij k_j 164161692a83SJed Brown 164261692a83SJed Brown The k_j can be recovered because Gamma is invertible. Let C be the lower triangular part of Gamma^{-1} and define 164361692a83SJed Brown 1644b70472e2SJed Brown $ A = Alpha Gamma^{-1}, bt^T = b^T Gamma^{-1} 164561692a83SJed Brown 164661692a83SJed Brown to rewrite the method as 164761692a83SJed Brown 164837fdd005SBarry Smith .vb 164937fdd005SBarry Smith [M/(h gamma_ii) - J] y_i = f(u_0 + sum_j a_ij y_j) + M sum_j (c_ij/h) y_j 165037fdd005SBarry Smith u_1 = u_0 + sum_j bt_j y_j 165137fdd005SBarry Smith .ve 165261692a83SJed Brown 165361692a83SJed Brown where we have introduced the mass matrix M. Continue by defining 165461692a83SJed Brown 165561692a83SJed Brown $ ydot_i = 1/(h gamma_ii) y_i - sum_j (c_ij/h) y_j 165661692a83SJed Brown 165761692a83SJed Brown or, more compactly in tensor notation 165861692a83SJed Brown 165961692a83SJed Brown $ Ydot = 1/h (Gamma^{-1} \otimes I) Y . 166061692a83SJed Brown 166161692a83SJed Brown Note that Gamma^{-1} is lower triangular. With this definition of Ydot in terms of known quantities and the current 166261692a83SJed Brown stage y_i, the stage equations reduce to performing one Newton step (typically with a lagged Jacobian) on the 166361692a83SJed Brown equation 166461692a83SJed Brown 1665f9c1d6abSBarry Smith $ g(u_0 + sum_j a_ij y_j + y_i, ydot_i) = 0 166661692a83SJed Brown 166761692a83SJed Brown with initial guess y_i = 0. 1668e27a552bSJed Brown 16691cc06b55SBarry Smith .seealso: [](ch_ts), `TSCreate()`, `TS`, `TSSetType()`, `TSRosWSetType()`, `TSRosWRegister()`, `TSROSWTHETA1`, `TSROSWTHETA2`, `TSROSW2M`, `TSROSW2P`, `TSROSWRA3PW`, `TSROSWRA34PW2`, `TSROSWRODAS3`, 1670bcf0153eSBarry Smith `TSROSWSANDU3`, `TSROSWASSP3P3S1C`, `TSROSWLASSP3P4S2C`, `TSROSWLLSSP3P4S2C`, `TSROSWGRK4T`, `TSROSWSHAMP4`, `TSROSWVELDD4`, `TSROSW4L`, `TSType` 1671e27a552bSJed Brown M*/ 1672d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode TSCreate_RosW(TS ts) 1673d71ae5a4SJacob Faibussowitsch { 167461692a83SJed Brown TS_RosW *ros; 1675e27a552bSJed Brown 1676e27a552bSJed Brown PetscFunctionBegin; 16779566063dSJacob Faibussowitsch PetscCall(TSRosWInitializePackage()); 1678e27a552bSJed Brown 1679e27a552bSJed Brown ts->ops->reset = TSReset_RosW; 1680e27a552bSJed Brown ts->ops->destroy = TSDestroy_RosW; 1681e27a552bSJed Brown ts->ops->view = TSView_RosW; 16829200755eSBarry Smith ts->ops->load = TSLoad_RosW; 1683e27a552bSJed Brown ts->ops->setup = TSSetUp_RosW; 1684e27a552bSJed Brown ts->ops->step = TSStep_RosW; 1685e27a552bSJed Brown ts->ops->interpolate = TSInterpolate_RosW; 16861c3436cfSJed Brown ts->ops->evaluatestep = TSEvaluateStep_RosW; 1687e27a552bSJed Brown ts->ops->setfromoptions = TSSetFromOptions_RosW; 1688e27a552bSJed Brown ts->ops->snesfunction = SNESTSFormFunction_RosW; 1689e27a552bSJed Brown ts->ops->snesjacobian = SNESTSFormJacobian_RosW; 1690e27a552bSJed Brown 1691efd4aadfSBarry Smith ts->usessnes = PETSC_TRUE; 1692efd4aadfSBarry Smith 16934dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&ros)); 169461692a83SJed Brown ts->data = (void *)ros; 1695e27a552bSJed Brown 16969566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSRosWGetType_C", TSRosWGetType_RosW)); 16979566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSRosWSetType_C", TSRosWSetType_RosW)); 16989566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSRosWSetRecomputeJacobian_C", TSRosWSetRecomputeJacobian_RosW)); 1699b39943a6SLisandro Dalcin 17009566063dSJacob Faibussowitsch PetscCall(TSRosWSetType(ts, TSRosWDefault)); 17013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1702e27a552bSJed Brown } 1703