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 1431d27aa22SBarry Smith TSROSWSANDU3 - Three stage third order L-stable Rosenbrock scheme {cite}`sandu_1997` 144ef3c5b88SJed Brown 145ef3c5b88SJed Brown By default, the Jacobian is only recomputed once per step. 146ef3c5b88SJed Brown 147ef3c5b88SJed Brown The third order method is L-stable, but not stiffly accurate. 148ef3c5b88SJed Brown The second order embedded method is strongly A-stable with R(infty) = 0.5. 149ef3c5b88SJed Brown The internal stages are L-stable. 1501d27aa22SBarry Smith This method is called ROS3 in {cite}`sandu_1997`. 151ef3c5b88SJed Brown 152bcf0153eSBarry Smith Level: intermediate 153bcf0153eSBarry Smith 1541cc06b55SBarry Smith .seealso: [](ch_ts), `TSROSW`, `TSROSWRODAS3` 155ef3c5b88SJed Brown M*/ 156ef3c5b88SJed Brown 157961f28d0SJed Brown /*MC 158961f28d0SJed Brown TSROSWASSP3P3S1C - A-stable Rosenbrock-W method with SSP explicit part, third order, three stages 159961f28d0SJed Brown 160961f28d0SJed Brown By default, the Jacobian is only recomputed once per step. 161961f28d0SJed Brown 162961f28d0SJed Brown A-stable SPP explicit order 3, 3 stages, CFL 1 (eff = 1/3) 163961f28d0SJed Brown 164bcf0153eSBarry Smith Level: intermediate 165bcf0153eSBarry Smith 1661cc06b55SBarry Smith .seealso: [](ch_ts), `TSROSW`, `TSROSWLASSP3P4S2C`, `TSROSWLLSSP3P4S2C`, `SSP` 167961f28d0SJed Brown M*/ 168961f28d0SJed Brown 169961f28d0SJed Brown /*MC 170998eb97aSJed Brown TSROSWLASSP3P4S2C - L-stable Rosenbrock-W method with SSP explicit part, third order, four stages 171961f28d0SJed Brown 172961f28d0SJed Brown By default, the Jacobian is only recomputed once per step. 173961f28d0SJed Brown 174961f28d0SJed Brown L-stable (A-stable embedded) SPP explicit order 3, 4 stages, CFL 2 (eff = 1/2) 175961f28d0SJed Brown 176bcf0153eSBarry Smith Level: intermediate 177bcf0153eSBarry Smith 1781cc06b55SBarry Smith .seealso: [](ch_ts), `TSROSW`, `TSROSWASSP3P3S1C`, `TSROSWLLSSP3P4S2C`, `TSSSP` 179961f28d0SJed Brown M*/ 180961f28d0SJed Brown 181961f28d0SJed Brown /*MC 182998eb97aSJed Brown TSROSWLLSSP3P4S2C - L-stable Rosenbrock-W method with SSP explicit part, third order, four stages 183961f28d0SJed Brown 184961f28d0SJed Brown By default, the Jacobian is only recomputed once per step. 185961f28d0SJed Brown 186961f28d0SJed Brown L-stable (L-stable embedded) SPP explicit order 3, 4 stages, CFL 2 (eff = 1/2) 187961f28d0SJed Brown 188bcf0153eSBarry Smith Level: intermediate 189bcf0153eSBarry Smith 1901cc06b55SBarry Smith .seealso: [](ch_ts), `TSROSW`, `TSROSWASSP3P3S1C`, `TSROSWLASSP3P4S2C`, `TSSSP` 191961f28d0SJed Brown M*/ 192961f28d0SJed Brown 19342faf41dSJed Brown /*MC 1941d27aa22SBarry Smith TSROSWGRK4T - four stage, fourth order Rosenbrock (not W) method from Kaps and Rentrop {cite}`kaps1979generalized` 19542faf41dSJed Brown 19642faf41dSJed Brown By default, the Jacobian is only recomputed once per step. 19742faf41dSJed Brown 19842faf41dSJed Brown A(89.3 degrees)-stable, |R(infty)| = 0.454. 19942faf41dSJed Brown 20042faf41dSJed Brown This method does not provide a dense output formula. 20142faf41dSJed Brown 202bcf0153eSBarry Smith Level: intermediate 203bcf0153eSBarry Smith 2041d27aa22SBarry Smith Note: 2051d27aa22SBarry Smith See Section 4 Table 7.2 in {cite}`wanner1996solving` 20642faf41dSJed Brown 2071cc06b55SBarry Smith .seealso: [](ch_ts), `TSROSW`, `TSROSWSHAMP4`, `TSROSWVELDD4`, `TSROSW4L` 20842faf41dSJed Brown M*/ 20942faf41dSJed Brown 21042faf41dSJed Brown /*MC 2111d27aa22SBarry Smith TSROSWSHAMP4 - four stage, fourth order Rosenbrock (not W) method from Shampine {cite}`shampine1982implementation` 21242faf41dSJed Brown 21342faf41dSJed Brown By default, the Jacobian is only recomputed once per step. 21442faf41dSJed Brown 21542faf41dSJed Brown A-stable, |R(infty)| = 1/3. 21642faf41dSJed Brown 21742faf41dSJed Brown This method does not provide a dense output formula. 21842faf41dSJed Brown 219bcf0153eSBarry Smith Level: intermediate 220bcf0153eSBarry Smith 2211d27aa22SBarry Smith Note: 22215229ffcSPierre Jolivet See Section 4 Table 7.2 in {cite}`wanner1996solving` 22342faf41dSJed Brown 2241cc06b55SBarry Smith .seealso: [](ch_ts), `TSROSW`, `TSROSWGRK4T`, `TSROSWVELDD4`, `TSROSW4L` 22542faf41dSJed Brown M*/ 22642faf41dSJed Brown 22742faf41dSJed Brown /*MC 2281d27aa22SBarry Smith TSROSWVELDD4 - four stage, fourth order Rosenbrock (not W) method from van Veldhuizen {cite}`veldhuizen1984d` 22942faf41dSJed Brown 23042faf41dSJed Brown By default, the Jacobian is only recomputed once per step. 23142faf41dSJed Brown 23242faf41dSJed Brown A(89.5 degrees)-stable, |R(infty)| = 0.24. 23342faf41dSJed Brown 23442faf41dSJed Brown This method does not provide a dense output formula. 23542faf41dSJed Brown 236bcf0153eSBarry Smith Level: intermediate 237bcf0153eSBarry Smith 2381d27aa22SBarry Smith Note: 2391d27aa22SBarry Smith See Section 4 Table 7.2 in {cite}`wanner1996solving` 24042faf41dSJed Brown 2411cc06b55SBarry Smith .seealso: [](ch_ts), `TSROSW`, `TSROSWGRK4T`, `TSROSWSHAMP4`, `TSROSW4L` 24242faf41dSJed Brown M*/ 24342faf41dSJed Brown 24442faf41dSJed Brown /*MC 24542faf41dSJed Brown TSROSW4L - four stage, fourth order Rosenbrock (not W) method 24642faf41dSJed Brown 24742faf41dSJed Brown By default, the Jacobian is only recomputed once per step. 24842faf41dSJed Brown 24942faf41dSJed Brown A-stable and L-stable 25042faf41dSJed Brown 25142faf41dSJed Brown This method does not provide a dense output formula. 25242faf41dSJed Brown 253bcf0153eSBarry Smith Level: intermediate 254bcf0153eSBarry Smith 2551d27aa22SBarry Smith Note: 25615229ffcSPierre Jolivet See Section 4 Table 7.2 in {cite}`wanner1996solving` 25742faf41dSJed Brown 2581cc06b55SBarry Smith .seealso: [](ch_ts), `TSROSW`, `TSROSWGRK4T`, `TSROSWSHAMP4`, `TSROSW4L` 25942faf41dSJed Brown M*/ 26042faf41dSJed Brown 261e27a552bSJed Brown /*@C 262bcf0153eSBarry Smith TSRosWRegisterAll - Registers all of the Rosenbrock-W methods in `TSROSW` 263e27a552bSJed Brown 2641d27aa22SBarry Smith Not Collective, but should be called by all MPI processes which will need the schemes to be registered 265e27a552bSJed Brown 266e27a552bSJed Brown Level: advanced 267e27a552bSJed Brown 2681cc06b55SBarry Smith .seealso: [](ch_ts), `TSROSW`, `TSRosWRegisterDestroy()` 269e27a552bSJed Brown @*/ 270d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRosWRegisterAll(void) 271d71ae5a4SJacob Faibussowitsch { 272e27a552bSJed Brown PetscFunctionBegin; 2733ba16761SJacob Faibussowitsch if (TSRosWRegisterAllCalled) PetscFunctionReturn(PETSC_SUCCESS); 274e27a552bSJed Brown TSRosWRegisterAllCalled = PETSC_TRUE; 275e27a552bSJed Brown 276e27a552bSJed Brown { 277bbd56ea5SKarl Rupp const PetscReal A = 0; 278bbd56ea5SKarl Rupp const PetscReal Gamma = 1; 279bbd56ea5SKarl Rupp const PetscReal b = 1; 280bbd56ea5SKarl Rupp const PetscReal binterpt = 1; 2811f80e275SEmil Constantinescu 2829566063dSJacob Faibussowitsch PetscCall(TSRosWRegister(TSROSWTHETA1, 1, 1, &A, &Gamma, &b, NULL, 1, &binterpt)); 2833606a31eSEmil Constantinescu } 2843606a31eSEmil Constantinescu 2853606a31eSEmil Constantinescu { 286bbd56ea5SKarl Rupp const PetscReal A = 0; 287bbd56ea5SKarl Rupp const PetscReal Gamma = 0.5; 288bbd56ea5SKarl Rupp const PetscReal b = 1; 289bbd56ea5SKarl Rupp const PetscReal binterpt = 1; 290bbd56ea5SKarl Rupp 2919566063dSJacob Faibussowitsch PetscCall(TSRosWRegister(TSROSWTHETA2, 2, 1, &A, &Gamma, &b, NULL, 1, &binterpt)); 2923606a31eSEmil Constantinescu } 2933606a31eSEmil Constantinescu 2943606a31eSEmil Constantinescu { 295da80777bSKarl 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. */ 296b16ce868SStefano Zampini const PetscReal A[2][2] = { 2979371c9d4SSatish Balay {0, 0}, 2989371c9d4SSatish Balay {1., 0} 299b16ce868SStefano Zampini }; 300b16ce868SStefano Zampini const PetscReal Gamma[2][2] = { 301b16ce868SStefano Zampini {1.707106781186547524401, 0 }, 302b16ce868SStefano Zampini {-2. * 1.707106781186547524401, 1.707106781186547524401} 303b16ce868SStefano Zampini }; 304b16ce868SStefano Zampini const PetscReal b[2] = {0.5, 0.5}; 305b16ce868SStefano Zampini const PetscReal b1[2] = {1.0, 0.0}; 3061f80e275SEmil Constantinescu PetscReal binterpt[2][2]; 307da80777bSKarl Rupp binterpt[0][0] = 1.707106781186547524401 - 1.0; 308da80777bSKarl Rupp binterpt[1][0] = 2.0 - 1.707106781186547524401; 309da80777bSKarl Rupp binterpt[0][1] = 1.707106781186547524401 - 1.5; 310da80777bSKarl Rupp binterpt[1][1] = 1.5 - 1.707106781186547524401; 311bbd56ea5SKarl Rupp 3129566063dSJacob Faibussowitsch PetscCall(TSRosWRegister(TSROSW2P, 2, 2, &A[0][0], &Gamma[0][0], b, b1, 2, &binterpt[0][0])); 313e27a552bSJed Brown } 314e27a552bSJed Brown { 315da80777bSKarl 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. */ 316b16ce868SStefano Zampini const PetscReal A[2][2] = { 3179371c9d4SSatish Balay {0, 0}, 3189371c9d4SSatish Balay {1., 0} 319b16ce868SStefano Zampini }; 320b16ce868SStefano Zampini const PetscReal Gamma[2][2] = { 321b16ce868SStefano Zampini {0.2928932188134524755992, 0 }, 322b16ce868SStefano Zampini {-2. * 0.2928932188134524755992, 0.2928932188134524755992} 323b16ce868SStefano Zampini }; 324b16ce868SStefano Zampini const PetscReal b[2] = {0.5, 0.5}; 325b16ce868SStefano Zampini const PetscReal b1[2] = {1.0, 0.0}; 3261f80e275SEmil Constantinescu PetscReal binterpt[2][2]; 327da80777bSKarl Rupp binterpt[0][0] = 0.2928932188134524755992 - 1.0; 328da80777bSKarl Rupp binterpt[1][0] = 2.0 - 0.2928932188134524755992; 329da80777bSKarl Rupp binterpt[0][1] = 0.2928932188134524755992 - 1.5; 330da80777bSKarl Rupp binterpt[1][1] = 1.5 - 0.2928932188134524755992; 331bbd56ea5SKarl Rupp 3329566063dSJacob Faibussowitsch PetscCall(TSRosWRegister(TSROSW2M, 2, 2, &A[0][0], &Gamma[0][0], b, b1, 2, &binterpt[0][0])); 333fe7e6d57SJed Brown } 334fe7e6d57SJed Brown { 335da80777bSKarl Rupp /*const PetscReal g = 7.8867513459481287e-01; Directly written in-place below */ 3361f80e275SEmil Constantinescu PetscReal binterpt[3][2]; 337b16ce868SStefano Zampini const PetscReal A[3][3] = { 3389371c9d4SSatish Balay {0, 0, 0}, 339fe7e6d57SJed Brown {1.5773502691896257e+00, 0, 0}, 3409371c9d4SSatish Balay {0.5, 0, 0} 341b16ce868SStefano Zampini }; 342b16ce868SStefano Zampini const PetscReal Gamma[3][3] = { 343b16ce868SStefano Zampini {7.8867513459481287e-01, 0, 0 }, 344b16ce868SStefano Zampini {-1.5773502691896257e+00, 7.8867513459481287e-01, 0 }, 345b16ce868SStefano Zampini {-6.7075317547305480e-01, -1.7075317547305482e-01, 7.8867513459481287e-01} 346b16ce868SStefano Zampini }; 347b16ce868SStefano Zampini const PetscReal b[3] = {1.0566243270259355e-01, 4.9038105676657971e-02, 8.4529946162074843e-01}; 348b16ce868SStefano Zampini const PetscReal b2[3] = {-1.7863279495408180e-01, 1. / 3., 8.4529946162074843e-01}; 3491f80e275SEmil Constantinescu 3501f80e275SEmil Constantinescu binterpt[0][0] = -0.8094010767585034; 3511f80e275SEmil Constantinescu binterpt[1][0] = -0.5; 3521f80e275SEmil Constantinescu binterpt[2][0] = 2.3094010767585034; 3531f80e275SEmil Constantinescu binterpt[0][1] = 0.9641016151377548; 3541f80e275SEmil Constantinescu binterpt[1][1] = 0.5; 3551f80e275SEmil Constantinescu binterpt[2][1] = -1.4641016151377548; 356bbd56ea5SKarl Rupp 3579566063dSJacob Faibussowitsch PetscCall(TSRosWRegister(TSROSWRA3PW, 3, 3, &A[0][0], &Gamma[0][0], b, b2, 2, &binterpt[0][0])); 358fe7e6d57SJed Brown } 359fe7e6d57SJed Brown { 3603ca35412SEmil Constantinescu PetscReal binterpt[4][3]; 361da80777bSKarl Rupp /*const PetscReal g = 4.3586652150845900e-01; Directly written in-place below */ 362b16ce868SStefano Zampini const PetscReal A[4][4] = { 3639371c9d4SSatish Balay {0, 0, 0, 0}, 364fe7e6d57SJed Brown {8.7173304301691801e-01, 0, 0, 0}, 365fe7e6d57SJed Brown {8.4457060015369423e-01, -1.1299064236484185e-01, 0, 0}, 3669371c9d4SSatish Balay {0, 0, 1., 0} 367b16ce868SStefano Zampini }; 368b16ce868SStefano Zampini const PetscReal Gamma[4][4] = { 369b16ce868SStefano Zampini {4.3586652150845900e-01, 0, 0, 0 }, 370b16ce868SStefano Zampini {-8.7173304301691801e-01, 4.3586652150845900e-01, 0, 0 }, 371b16ce868SStefano Zampini {-9.0338057013044082e-01, 5.4180672388095326e-02, 4.3586652150845900e-01, 0 }, 372b16ce868SStefano Zampini {2.4212380706095346e-01, -1.2232505839045147e+00, 5.4526025533510214e-01, 4.3586652150845900e-01} 373b16ce868SStefano Zampini }; 374b16ce868SStefano Zampini const PetscReal b[4] = {2.4212380706095346e-01, -1.2232505839045147e+00, 1.5452602553351020e+00, 4.3586652150845900e-01}; 375b16ce868SStefano Zampini const PetscReal b2[4] = {3.7810903145819369e-01, -9.6042292212423178e-02, 5.0000000000000000e-01, 2.1793326075422950e-01}; 3763ca35412SEmil Constantinescu 3773ca35412SEmil Constantinescu binterpt[0][0] = 1.0564298455794094; 3783ca35412SEmil Constantinescu binterpt[1][0] = 2.296429974281067; 3793ca35412SEmil Constantinescu binterpt[2][0] = -1.307599564525376; 3803ca35412SEmil Constantinescu binterpt[3][0] = -1.045260255335102; 3813ca35412SEmil Constantinescu binterpt[0][1] = -1.3864882699759573; 3823ca35412SEmil Constantinescu binterpt[1][1] = -8.262611700275677; 3833ca35412SEmil Constantinescu binterpt[2][1] = 7.250979895056055; 3843ca35412SEmil Constantinescu binterpt[3][1] = 2.398120075195581; 3853ca35412SEmil Constantinescu binterpt[0][2] = 0.5721822314575016; 3863ca35412SEmil Constantinescu binterpt[1][2] = 4.742931142090097; 3873ca35412SEmil Constantinescu binterpt[2][2] = -4.398120075195578; 3883ca35412SEmil Constantinescu binterpt[3][2] = -0.9169932983520199; 3893ca35412SEmil Constantinescu 3909566063dSJacob Faibussowitsch PetscCall(TSRosWRegister(TSROSWRA34PW2, 3, 4, &A[0][0], &Gamma[0][0], b, b2, 3, &binterpt[0][0])); 391e27a552bSJed Brown } 392ef3c5b88SJed Brown { 393da80777bSKarl Rupp /* const PetscReal g = 0.5; Directly written in-place below */ 394b16ce868SStefano Zampini const PetscReal A[4][4] = { 3959371c9d4SSatish Balay {0, 0, 0, 0}, 396ef3c5b88SJed Brown {0, 0, 0, 0}, 397ef3c5b88SJed Brown {1., 0, 0, 0}, 3989371c9d4SSatish Balay {0.75, -0.25, 0.5, 0} 399b16ce868SStefano Zampini }; 400b16ce868SStefano Zampini const PetscReal Gamma[4][4] = { 401b16ce868SStefano Zampini {0.5, 0, 0, 0 }, 402b16ce868SStefano Zampini {1., 0.5, 0, 0 }, 403b16ce868SStefano Zampini {-0.25, -0.25, 0.5, 0 }, 404b16ce868SStefano Zampini {1. / 12, 1. / 12, -2. / 3, 0.5} 405b16ce868SStefano Zampini }; 406b16ce868SStefano Zampini const PetscReal b[4] = {5. / 6, -1. / 6, -1. / 6, 0.5}; 407b16ce868SStefano Zampini const PetscReal b2[4] = {0.75, -0.25, 0.5, 0}; 408bbd56ea5SKarl Rupp 4099566063dSJacob Faibussowitsch PetscCall(TSRosWRegister(TSROSWRODAS3, 3, 4, &A[0][0], &Gamma[0][0], b, b2, 0, NULL)); 410ef3c5b88SJed Brown } 411ef3c5b88SJed Brown { 412da80777bSKarl Rupp /*const PetscReal g = 0.43586652150845899941601945119356; Directly written in-place below */ 413b16ce868SStefano Zampini const PetscReal A[3][3] = { 4149371c9d4SSatish Balay {0, 0, 0}, 415da80777bSKarl Rupp {0.43586652150845899941601945119356, 0, 0}, 4169371c9d4SSatish Balay {0.43586652150845899941601945119356, 0, 0} 417b16ce868SStefano Zampini }; 418b16ce868SStefano Zampini const PetscReal Gamma[3][3] = { 419b16ce868SStefano Zampini {0.43586652150845899941601945119356, 0, 0 }, 420b16ce868SStefano Zampini {-0.19294655696029095575009695436041, 0.43586652150845899941601945119356, 0 }, 421b16ce868SStefano Zampini {0, 1.74927148125794685173529749738960, 0.43586652150845899941601945119356} 422b16ce868SStefano Zampini }; 423b16ce868SStefano Zampini const PetscReal b[3] = {-0.75457412385404315829818998646589, 1.94100407061964420292840123379419, -0.18642994676560104463021124732829}; 424b16ce868SStefano Zampini const PetscReal b2[3] = {-1.53358745784149585370766523913002, 2.81745131148625772213931745457622, -0.28386385364476186843165221544619}; 4251f80e275SEmil Constantinescu 4261f80e275SEmil Constantinescu PetscReal binterpt[3][2]; 4271f80e275SEmil Constantinescu binterpt[0][0] = 3.793692883777660870425141387941; 4281f80e275SEmil Constantinescu binterpt[1][0] = -2.918692883777660870425141387941; 4291f80e275SEmil Constantinescu binterpt[2][0] = 0.125; 4301f80e275SEmil Constantinescu binterpt[0][1] = -0.725741064379812106687651020584; 4311f80e275SEmil Constantinescu binterpt[1][1] = 0.559074397713145440020984353917; 4321f80e275SEmil Constantinescu binterpt[2][1] = 0.16666666666666666666666666666667; 4331f80e275SEmil Constantinescu 4349566063dSJacob Faibussowitsch PetscCall(TSRosWRegister(TSROSWSANDU3, 3, 3, &A[0][0], &Gamma[0][0], b, b2, 2, &binterpt[0][0])); 435ef3c5b88SJed Brown } 436b1c69cc3SEmil Constantinescu { 437da80777bSKarl Rupp /*const PetscReal s3 = PetscSqrtReal(3.),g = (3.0+s3)/6.0; 438da80777bSKarl Rupp * Direct evaluation: s3 = 1.732050807568877293527; 439da80777bSKarl Rupp * g = 0.7886751345948128822546; 440da80777bSKarl Rupp * Values are directly inserted below to ensure availability at compile time (compiler warnings otherwise...) */ 441b16ce868SStefano Zampini const PetscReal A[3][3] = { 4429371c9d4SSatish Balay {0, 0, 0}, 443b1c69cc3SEmil Constantinescu {1, 0, 0}, 4449371c9d4SSatish Balay {0.25, 0.25, 0} 445b16ce868SStefano Zampini }; 446b16ce868SStefano Zampini const PetscReal Gamma[3][3] = { 447b16ce868SStefano Zampini {0, 0, 0 }, 448b16ce868SStefano Zampini {(-3.0 - 1.732050807568877293527) / 6.0, 0.7886751345948128822546, 0 }, 449b16ce868SStefano Zampini {(-3.0 - 1.732050807568877293527) / 24.0, (-3.0 - 1.732050807568877293527) / 8.0, 0.7886751345948128822546} 450b16ce868SStefano Zampini }; 451b16ce868SStefano Zampini const PetscReal b[3] = {1. / 6., 1. / 6., 2. / 3.}; 452b16ce868SStefano Zampini const PetscReal b2[3] = {1. / 4., 1. / 4., 1. / 2.}; 453c0cb691aSEmil Constantinescu PetscReal binterpt[3][2]; 454da80777bSKarl Rupp 455c0cb691aSEmil Constantinescu binterpt[0][0] = 0.089316397477040902157517886164709; 456c0cb691aSEmil Constantinescu binterpt[1][0] = -0.91068360252295909784248211383529; 457c0cb691aSEmil Constantinescu binterpt[2][0] = 1.8213672050459181956849642276706; 458c0cb691aSEmil Constantinescu binterpt[0][1] = 0.077350269189625764509148780501957; 459c0cb691aSEmil Constantinescu binterpt[1][1] = 1.077350269189625764509148780502; 460c0cb691aSEmil Constantinescu binterpt[2][1] = -1.1547005383792515290182975610039; 461bbd56ea5SKarl Rupp 4629566063dSJacob Faibussowitsch PetscCall(TSRosWRegister(TSROSWASSP3P3S1C, 3, 3, &A[0][0], &Gamma[0][0], b, b2, 2, &binterpt[0][0])); 463b1c69cc3SEmil Constantinescu } 464b1c69cc3SEmil Constantinescu 465b1c69cc3SEmil Constantinescu { 466b16ce868SStefano Zampini const PetscReal A[4][4] = { 4679371c9d4SSatish Balay {0, 0, 0, 0}, 468b1c69cc3SEmil Constantinescu {1. / 2., 0, 0, 0}, 469b1c69cc3SEmil Constantinescu {1. / 2., 1. / 2., 0, 0}, 4709371c9d4SSatish Balay {1. / 6., 1. / 6., 1. / 6., 0} 471b16ce868SStefano Zampini }; 472b16ce868SStefano Zampini const PetscReal Gamma[4][4] = { 473b16ce868SStefano Zampini {1. / 2., 0, 0, 0}, 474b16ce868SStefano Zampini {0.0, 1. / 4., 0, 0}, 475b16ce868SStefano Zampini {-2., -2. / 3., 2. / 3., 0}, 476b16ce868SStefano Zampini {1. / 2., 5. / 36., -2. / 9, 0} 477b16ce868SStefano Zampini }; 478b16ce868SStefano Zampini const PetscReal b[4] = {1. / 6., 1. / 6., 1. / 6., 1. / 2.}; 479b16ce868SStefano Zampini const PetscReal b2[4] = {1. / 8., 3. / 4., 1. / 8., 0}; 480c0cb691aSEmil Constantinescu PetscReal binterpt[4][3]; 481da80777bSKarl Rupp 482c0cb691aSEmil Constantinescu binterpt[0][0] = 6.25; 483c0cb691aSEmil Constantinescu binterpt[1][0] = -30.25; 484c0cb691aSEmil Constantinescu binterpt[2][0] = 1.75; 485c0cb691aSEmil Constantinescu binterpt[3][0] = 23.25; 486c0cb691aSEmil Constantinescu binterpt[0][1] = -9.75; 487c0cb691aSEmil Constantinescu binterpt[1][1] = 58.75; 488c0cb691aSEmil Constantinescu binterpt[2][1] = -3.25; 489c0cb691aSEmil Constantinescu binterpt[3][1] = -45.75; 490c0cb691aSEmil Constantinescu binterpt[0][2] = 3.6666666666666666666666666666667; 491c0cb691aSEmil Constantinescu binterpt[1][2] = -28.333333333333333333333333333333; 492c0cb691aSEmil Constantinescu binterpt[2][2] = 1.6666666666666666666666666666667; 493c0cb691aSEmil Constantinescu binterpt[3][2] = 23.; 494bbd56ea5SKarl Rupp 4959566063dSJacob Faibussowitsch PetscCall(TSRosWRegister(TSROSWLASSP3P4S2C, 3, 4, &A[0][0], &Gamma[0][0], b, b2, 3, &binterpt[0][0])); 496b1c69cc3SEmil Constantinescu } 497b1c69cc3SEmil Constantinescu 498b1c69cc3SEmil Constantinescu { 499b16ce868SStefano Zampini const PetscReal A[4][4] = { 5009371c9d4SSatish Balay {0, 0, 0, 0}, 501b1c69cc3SEmil Constantinescu {1. / 2., 0, 0, 0}, 502b1c69cc3SEmil Constantinescu {1. / 2., 1. / 2., 0, 0}, 5039371c9d4SSatish Balay {1. / 6., 1. / 6., 1. / 6., 0} 504b16ce868SStefano Zampini }; 505b16ce868SStefano Zampini const PetscReal Gamma[4][4] = { 506b16ce868SStefano Zampini {1. / 2., 0, 0, 0}, 507b16ce868SStefano Zampini {0.0, 3. / 4., 0, 0}, 508b16ce868SStefano Zampini {-2. / 3., -23. / 9., 2. / 9., 0}, 509b16ce868SStefano Zampini {1. / 18., 65. / 108., -2. / 27, 0} 510b16ce868SStefano Zampini }; 511b16ce868SStefano Zampini const PetscReal b[4] = {1. / 6., 1. / 6., 1. / 6., 1. / 2.}; 512b16ce868SStefano Zampini const PetscReal b2[4] = {3. / 16., 10. / 16., 3. / 16., 0}; 513c0cb691aSEmil Constantinescu PetscReal binterpt[4][3]; 514da80777bSKarl Rupp 515c0cb691aSEmil Constantinescu binterpt[0][0] = 1.6911764705882352941176470588235; 516c0cb691aSEmil Constantinescu binterpt[1][0] = 3.6813725490196078431372549019608; 517c0cb691aSEmil Constantinescu binterpt[2][0] = 0.23039215686274509803921568627451; 518c0cb691aSEmil Constantinescu binterpt[3][0] = -4.6029411764705882352941176470588; 519c0cb691aSEmil Constantinescu binterpt[0][1] = -0.95588235294117647058823529411765; 520c0cb691aSEmil Constantinescu binterpt[1][1] = -6.2401960784313725490196078431373; 521c0cb691aSEmil Constantinescu binterpt[2][1] = -0.31862745098039215686274509803922; 522c0cb691aSEmil Constantinescu binterpt[3][1] = 7.5147058823529411764705882352941; 523c0cb691aSEmil Constantinescu binterpt[0][2] = -0.56862745098039215686274509803922; 524c0cb691aSEmil Constantinescu binterpt[1][2] = 2.7254901960784313725490196078431; 525c0cb691aSEmil Constantinescu binterpt[2][2] = 0.25490196078431372549019607843137; 526c0cb691aSEmil Constantinescu binterpt[3][2] = -2.4117647058823529411764705882353; 527bbd56ea5SKarl Rupp 5289566063dSJacob Faibussowitsch PetscCall(TSRosWRegister(TSROSWLLSSP3P4S2C, 3, 4, &A[0][0], &Gamma[0][0], b, b2, 3, &binterpt[0][0])); 529b1c69cc3SEmil Constantinescu } 530753f8adbSEmil Constantinescu 531753f8adbSEmil Constantinescu { 532753f8adbSEmil Constantinescu PetscReal A[4][4], Gamma[4][4], b[4], b2[4]; 5333ca35412SEmil Constantinescu PetscReal binterpt[4][3]; 534753f8adbSEmil Constantinescu 535753f8adbSEmil Constantinescu Gamma[0][0] = 0.4358665215084589994160194475295062513822671686978816; 5369371c9d4SSatish Balay Gamma[0][1] = 0; 5379371c9d4SSatish Balay Gamma[0][2] = 0; 5389371c9d4SSatish Balay Gamma[0][3] = 0; 539753f8adbSEmil Constantinescu Gamma[1][0] = -1.997527830934941248426324674704153457289527280554476; 540753f8adbSEmil Constantinescu Gamma[1][1] = 0.4358665215084589994160194475295062513822671686978816; 5419371c9d4SSatish Balay Gamma[1][2] = 0; 5429371c9d4SSatish Balay Gamma[1][3] = 0; 543753f8adbSEmil Constantinescu Gamma[2][0] = -1.007948511795029620852002345345404191008352770119903; 544753f8adbSEmil Constantinescu Gamma[2][1] = -0.004648958462629345562774289390054679806993396798458131; 545753f8adbSEmil Constantinescu Gamma[2][2] = 0.4358665215084589994160194475295062513822671686978816; 54605e8e825SJed Brown Gamma[2][3] = 0; 547753f8adbSEmil Constantinescu Gamma[3][0] = -0.6685429734233467180451604600279552604364311322650783; 548753f8adbSEmil Constantinescu Gamma[3][1] = 0.6056625986449338476089525334450053439525178740492984; 549753f8adbSEmil Constantinescu Gamma[3][2] = -0.9717899277217721234705114616271378792182450260943198; 550753f8adbSEmil Constantinescu Gamma[3][3] = 0; 551753f8adbSEmil Constantinescu 5529371c9d4SSatish Balay A[0][0] = 0; 5539371c9d4SSatish Balay A[0][1] = 0; 5549371c9d4SSatish Balay A[0][2] = 0; 5559371c9d4SSatish Balay A[0][3] = 0; 556753f8adbSEmil Constantinescu A[1][0] = 0.8717330430169179988320388950590125027645343373957631; 5579371c9d4SSatish Balay A[1][1] = 0; 5589371c9d4SSatish Balay A[1][2] = 0; 5599371c9d4SSatish Balay A[1][3] = 0; 560753f8adbSEmil Constantinescu A[2][0] = 0.5275890119763004115618079766722914408876108660811028; 561753f8adbSEmil Constantinescu A[2][1] = 0.07241098802369958843819203208518599088698057726988732; 5629371c9d4SSatish Balay A[2][2] = 0; 5639371c9d4SSatish Balay A[2][3] = 0; 564753f8adbSEmil Constantinescu A[3][0] = 0.3990960076760701320627260685975778145384666450351314; 565753f8adbSEmil Constantinescu A[3][1] = -0.4375576546135194437228463747348862825846903771419953; 566753f8adbSEmil Constantinescu A[3][2] = 1.038461646937449311660120300601880176655352737312713; 56705e8e825SJed Brown A[3][3] = 0; 568753f8adbSEmil Constantinescu 569753f8adbSEmil Constantinescu b[0] = 0.1876410243467238251612921333138006734899663569186926; 570753f8adbSEmil Constantinescu b[1] = -0.5952974735769549480478230473706443582188442040780541; 571753f8adbSEmil Constantinescu b[2] = 0.9717899277217721234705114616271378792182450260943198; 572753f8adbSEmil Constantinescu b[3] = 0.4358665215084589994160194475295062513822671686978816; 573753f8adbSEmil Constantinescu 574753f8adbSEmil Constantinescu b2[0] = 0.2147402862233891404862383521089097657790734483804460; 575753f8adbSEmil Constantinescu b2[1] = -0.4851622638849390928209050538171743017757490232519684; 576753f8adbSEmil Constantinescu b2[2] = 0.8687250025203875511662123688667549217531982787600080; 577753f8adbSEmil Constantinescu b2[3] = 0.4016969751411624011684543450940068201770721128357014; 578753f8adbSEmil Constantinescu 5793ca35412SEmil Constantinescu binterpt[0][0] = 2.2565812720167954547104627844105; 5803ca35412SEmil Constantinescu binterpt[1][0] = 1.349166413351089573796243820819; 5813ca35412SEmil Constantinescu binterpt[2][0] = -2.4695174540533503758652847586647; 5823ca35412SEmil Constantinescu binterpt[3][0] = -0.13623023131453465264142184656474; 5833ca35412SEmil Constantinescu binterpt[0][1] = -3.0826699111559187902922463354557; 5843ca35412SEmil Constantinescu binterpt[1][1] = -2.4689115685996042534544925650515; 5853ca35412SEmil Constantinescu binterpt[2][1] = 5.7428279814696677152129332773553; 5863ca35412SEmil Constantinescu binterpt[3][1] = -0.19124650171414467146619437684812; 5873ca35412SEmil Constantinescu binterpt[0][2] = 1.0137296634858471607430756831148; 5883ca35412SEmil Constantinescu binterpt[1][2] = 0.52444768167155973161042570784064; 5893ca35412SEmil Constantinescu binterpt[2][2] = -2.3015205996945452158771370439586; 5903ca35412SEmil Constantinescu binterpt[3][2] = 0.76334325453713832352363565300308; 591f4aed992SEmil Constantinescu 5929566063dSJacob Faibussowitsch PetscCall(TSRosWRegister(TSROSWARK3, 3, 4, &A[0][0], &Gamma[0][0], b, b2, 3, &binterpt[0][0])); 593753f8adbSEmil Constantinescu } 5949566063dSJacob Faibussowitsch PetscCall(TSRosWRegisterRos4(TSROSWGRK4T, 0.231, PETSC_DEFAULT, PETSC_DEFAULT, 0, -0.1282612945269037e+01)); 5959566063dSJacob Faibussowitsch PetscCall(TSRosWRegisterRos4(TSROSWSHAMP4, 0.5, PETSC_DEFAULT, PETSC_DEFAULT, 0, 125. / 108.)); 5969566063dSJacob Faibussowitsch PetscCall(TSRosWRegisterRos4(TSROSWVELDD4, 0.22570811482256823492, PETSC_DEFAULT, PETSC_DEFAULT, 0, -1.355958941201148)); 5979566063dSJacob Faibussowitsch PetscCall(TSRosWRegisterRos4(TSROSW4L, 0.57282, PETSC_DEFAULT, PETSC_DEFAULT, 0, -1.093502252409163)); 5983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 599e27a552bSJed Brown } 600e27a552bSJed Brown 601e27a552bSJed Brown /*@C 602bcf0153eSBarry Smith TSRosWRegisterDestroy - Frees the list of schemes that were registered by `TSRosWRegister()`. 603e27a552bSJed Brown 604e27a552bSJed Brown Not Collective 605e27a552bSJed Brown 606e27a552bSJed Brown Level: advanced 607e27a552bSJed Brown 6081cc06b55SBarry Smith .seealso: [](ch_ts), `TSRosWRegister()`, `TSRosWRegisterAll()` 609e27a552bSJed Brown @*/ 610d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRosWRegisterDestroy(void) 611d71ae5a4SJacob Faibussowitsch { 61261692a83SJed Brown RosWTableauLink link; 613e27a552bSJed Brown 614e27a552bSJed Brown PetscFunctionBegin; 61561692a83SJed Brown while ((link = RosWTableauList)) { 61661692a83SJed Brown RosWTableau t = &link->tab; 61761692a83SJed Brown RosWTableauList = link->next; 6189566063dSJacob Faibussowitsch PetscCall(PetscFree5(t->A, t->Gamma, t->b, t->ASum, t->GammaSum)); 6199566063dSJacob Faibussowitsch PetscCall(PetscFree5(t->At, t->bt, t->GammaInv, t->GammaZeroDiag, t->GammaExplicitCorr)); 6209566063dSJacob Faibussowitsch PetscCall(PetscFree2(t->bembed, t->bembedt)); 6219566063dSJacob Faibussowitsch PetscCall(PetscFree(t->binterpt)); 6229566063dSJacob Faibussowitsch PetscCall(PetscFree(t->name)); 6239566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 624e27a552bSJed Brown } 625e27a552bSJed Brown TSRosWRegisterAllCalled = PETSC_FALSE; 6263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 627e27a552bSJed Brown } 628e27a552bSJed Brown 629e27a552bSJed Brown /*@C 630bcf0153eSBarry Smith TSRosWInitializePackage - This function initializes everything in the `TSROSW` package. It is called 631bcf0153eSBarry Smith from `TSInitializePackage()`. 632e27a552bSJed Brown 633e27a552bSJed Brown Level: developer 634e27a552bSJed Brown 6351cc06b55SBarry Smith .seealso: [](ch_ts), `TSROSW`, `PetscInitialize()`, `TSRosWFinalizePackage()` 636e27a552bSJed Brown @*/ 637d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRosWInitializePackage(void) 638d71ae5a4SJacob Faibussowitsch { 639e27a552bSJed Brown PetscFunctionBegin; 6403ba16761SJacob Faibussowitsch if (TSRosWPackageInitialized) PetscFunctionReturn(PETSC_SUCCESS); 641e27a552bSJed Brown TSRosWPackageInitialized = PETSC_TRUE; 6429566063dSJacob Faibussowitsch PetscCall(TSRosWRegisterAll()); 6439566063dSJacob Faibussowitsch PetscCall(PetscRegisterFinalize(TSRosWFinalizePackage)); 6443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 645e27a552bSJed Brown } 646e27a552bSJed Brown 647e27a552bSJed Brown /*@C 648bcf0153eSBarry Smith TSRosWFinalizePackage - This function destroys everything in the `TSROSW` package. It is 649bcf0153eSBarry Smith called from `PetscFinalize()`. 650e27a552bSJed Brown 651e27a552bSJed Brown Level: developer 652e27a552bSJed Brown 6531cc06b55SBarry Smith .seealso: [](ch_ts), `TSROSW`, `PetscFinalize()`, `TSRosWInitializePackage()` 654e27a552bSJed Brown @*/ 655d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRosWFinalizePackage(void) 656d71ae5a4SJacob Faibussowitsch { 657e27a552bSJed Brown PetscFunctionBegin; 658e27a552bSJed Brown TSRosWPackageInitialized = PETSC_FALSE; 6599566063dSJacob Faibussowitsch PetscCall(TSRosWRegisterDestroy()); 6603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 661e27a552bSJed Brown } 662e27a552bSJed Brown 663e27a552bSJed Brown /*@C 664bcf0153eSBarry Smith TSRosWRegister - register a `TSROSW`, Rosenbrock W scheme by providing the entries in the Butcher tableau and optionally embedded approximations and interpolation 665e27a552bSJed Brown 666e27a552bSJed Brown Not Collective, but the same schemes should be registered on all processes on which they will be used 667e27a552bSJed Brown 668e27a552bSJed Brown Input Parameters: 669e27a552bSJed Brown + name - identifier for method 670e27a552bSJed Brown . order - approximation order of method 671e27a552bSJed Brown . s - number of stages, this is the dimension of the matrices below 67261692a83SJed Brown . A - Table of propagated stage coefficients (dimension s*s, row-major), strictly lower triangular 67361692a83SJed Brown . Gamma - Table of coefficients in implicit stage equations (dimension s*s, row-major), lower triangular with nonzero diagonal 674fe7e6d57SJed Brown . b - Step completion table (dimension s) 6750298fd71SBarry Smith . bembed - Step completion table for a scheme of order one less (dimension s, NULL if no embedded scheme is available) 676f4aed992SEmil Constantinescu . pinterp - Order of the interpolation scheme, equal to the number of columns of binterpt 67742faf41dSJed Brown - binterpt - Coefficients of the interpolation formula (dimension s*pinterp) 678e27a552bSJed Brown 679e27a552bSJed Brown Level: advanced 680e27a552bSJed Brown 681bcf0153eSBarry Smith Note: 682bcf0153eSBarry Smith Several Rosenbrock W methods are provided, this function is only needed to create new methods. 683bcf0153eSBarry Smith 6841cc06b55SBarry Smith .seealso: [](ch_ts), `TSROSW` 685e27a552bSJed Brown @*/ 686d71ae5a4SJacob 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[]) 687d71ae5a4SJacob Faibussowitsch { 68861692a83SJed Brown RosWTableauLink link; 68961692a83SJed Brown RosWTableau t; 69061692a83SJed Brown PetscInt i, j, k; 69161692a83SJed Brown PetscScalar *GammaInv; 692e27a552bSJed Brown 693e27a552bSJed Brown PetscFunctionBegin; 6944f572ea9SToby Isaac PetscAssertPointer(name, 1); 6954f572ea9SToby Isaac PetscAssertPointer(A, 4); 6964f572ea9SToby Isaac PetscAssertPointer(Gamma, 5); 6974f572ea9SToby Isaac PetscAssertPointer(b, 6); 6984f572ea9SToby Isaac if (bembed) PetscAssertPointer(bembed, 7); 699fe7e6d57SJed Brown 7009566063dSJacob Faibussowitsch PetscCall(TSRosWInitializePackage()); 7019566063dSJacob Faibussowitsch PetscCall(PetscNew(&link)); 702e27a552bSJed Brown t = &link->tab; 7039566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(name, &t->name)); 704e27a552bSJed Brown t->order = order; 705e27a552bSJed Brown t->s = s; 7069566063dSJacob Faibussowitsch PetscCall(PetscMalloc5(s * s, &t->A, s * s, &t->Gamma, s, &t->b, s, &t->ASum, s, &t->GammaSum)); 7079566063dSJacob Faibussowitsch PetscCall(PetscMalloc5(s * s, &t->At, s, &t->bt, s * s, &t->GammaInv, s, &t->GammaZeroDiag, s * s, &t->GammaExplicitCorr)); 7089566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(t->A, A, s * s)); 7099566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(t->Gamma, Gamma, s * s)); 7109566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(t->GammaExplicitCorr, Gamma, s * s)); 7119566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(t->b, b, s)); 712fe7e6d57SJed Brown if (bembed) { 7139566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(s, &t->bembed, s, &t->bembedt)); 7149566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(t->bembed, bembed, s)); 715fe7e6d57SJed Brown } 71661692a83SJed Brown for (i = 0; i < s; i++) { 71761692a83SJed Brown t->ASum[i] = 0; 71861692a83SJed Brown t->GammaSum[i] = 0; 71961692a83SJed Brown for (j = 0; j < s; j++) { 72061692a83SJed Brown t->ASum[i] += A[i * s + j]; 721fe7e6d57SJed Brown t->GammaSum[i] += Gamma[i * s + j]; 72261692a83SJed Brown } 72361692a83SJed Brown } 7249566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(s * s, &GammaInv)); /* Need to use Scalar for inverse, then convert back to Real */ 72561692a83SJed Brown for (i = 0; i < s * s; i++) GammaInv[i] = Gamma[i]; 726fd96d5b0SEmil Constantinescu for (i = 0; i < s; i++) { 727fd96d5b0SEmil Constantinescu if (Gamma[i * s + i] == 0.0) { 728fd96d5b0SEmil Constantinescu GammaInv[i * s + i] = 1.0; 729c17803e7SJed Brown t->GammaZeroDiag[i] = PETSC_TRUE; 730fd96d5b0SEmil Constantinescu } else { 731c17803e7SJed Brown t->GammaZeroDiag[i] = PETSC_FALSE; 732fd96d5b0SEmil Constantinescu } 733fd96d5b0SEmil Constantinescu } 734fd96d5b0SEmil Constantinescu 73561692a83SJed Brown switch (s) { 736d71ae5a4SJacob Faibussowitsch case 1: 737d71ae5a4SJacob Faibussowitsch GammaInv[0] = 1. / GammaInv[0]; 738d71ae5a4SJacob Faibussowitsch break; 739d71ae5a4SJacob Faibussowitsch case 2: 740d71ae5a4SJacob Faibussowitsch PetscCall(PetscKernel_A_gets_inverse_A_2(GammaInv, 0, PETSC_FALSE, NULL)); 741d71ae5a4SJacob Faibussowitsch break; 742d71ae5a4SJacob Faibussowitsch case 3: 743d71ae5a4SJacob Faibussowitsch PetscCall(PetscKernel_A_gets_inverse_A_3(GammaInv, 0, PETSC_FALSE, NULL)); 744d71ae5a4SJacob Faibussowitsch break; 745d71ae5a4SJacob Faibussowitsch case 4: 746d71ae5a4SJacob Faibussowitsch PetscCall(PetscKernel_A_gets_inverse_A_4(GammaInv, 0, PETSC_FALSE, NULL)); 747d71ae5a4SJacob Faibussowitsch break; 74861692a83SJed Brown case 5: { 74961692a83SJed Brown PetscInt ipvt5[5]; 75061692a83SJed Brown MatScalar work5[5 * 5]; 7519371c9d4SSatish Balay PetscCall(PetscKernel_A_gets_inverse_A_5(GammaInv, ipvt5, work5, 0, PETSC_FALSE, NULL)); 7529371c9d4SSatish Balay break; 75361692a83SJed Brown } 754d71ae5a4SJacob Faibussowitsch case 6: 755d71ae5a4SJacob Faibussowitsch PetscCall(PetscKernel_A_gets_inverse_A_6(GammaInv, 0, PETSC_FALSE, NULL)); 756d71ae5a4SJacob Faibussowitsch break; 757d71ae5a4SJacob Faibussowitsch case 7: 758d71ae5a4SJacob Faibussowitsch PetscCall(PetscKernel_A_gets_inverse_A_7(GammaInv, 0, PETSC_FALSE, NULL)); 759d71ae5a4SJacob Faibussowitsch break; 760d71ae5a4SJacob Faibussowitsch default: 761d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Not implemented for %" PetscInt_FMT " stages", s); 76261692a83SJed Brown } 76361692a83SJed Brown for (i = 0; i < s * s; i++) t->GammaInv[i] = PetscRealPart(GammaInv[i]); 7649566063dSJacob Faibussowitsch PetscCall(PetscFree(GammaInv)); 76543b21953SEmil Constantinescu 76643b21953SEmil Constantinescu for (i = 0; i < s; i++) { 76743b21953SEmil Constantinescu for (k = 0; k < i + 1; k++) { 76843b21953SEmil Constantinescu t->GammaExplicitCorr[i * s + k] = (t->GammaExplicitCorr[i * s + k]) * (t->GammaInv[k * s + k]); 769ad540459SPierre Jolivet for (j = k + 1; j < i + 1; j++) t->GammaExplicitCorr[i * s + k] += (t->GammaExplicitCorr[i * s + j]) * (t->GammaInv[j * s + k]); 77043b21953SEmil Constantinescu } 77143b21953SEmil Constantinescu } 77243b21953SEmil Constantinescu 77361692a83SJed Brown for (i = 0; i < s; i++) { 77461692a83SJed Brown for (j = 0; j < s; j++) { 77561692a83SJed Brown t->At[i * s + j] = 0; 776ad540459SPierre Jolivet for (k = 0; k < s; k++) t->At[i * s + j] += t->A[i * s + k] * t->GammaInv[k * s + j]; 77761692a83SJed Brown } 77861692a83SJed Brown t->bt[i] = 0; 779ad540459SPierre Jolivet for (j = 0; j < s; j++) t->bt[i] += t->b[j] * t->GammaInv[j * s + i]; 780fe7e6d57SJed Brown if (bembed) { 781fe7e6d57SJed Brown t->bembedt[i] = 0; 782ad540459SPierre Jolivet for (j = 0; j < s; j++) t->bembedt[i] += t->bembed[j] * t->GammaInv[j * s + i]; 783fe7e6d57SJed Brown } 78461692a83SJed Brown } 7858d59e960SJed Brown t->ccfl = 1.0; /* Fix this */ 7868d59e960SJed Brown 787f4aed992SEmil Constantinescu t->pinterp = pinterp; 7889566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(s * pinterp, &t->binterpt)); 7899566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(t->binterpt, binterpt, s * pinterp)); 79061692a83SJed Brown link->next = RosWTableauList; 79161692a83SJed Brown RosWTableauList = link; 7923ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 793e27a552bSJed Brown } 794e27a552bSJed Brown 79542faf41dSJed Brown /*@C 796fd292e60Sprj- TSRosWRegisterRos4 - register a fourth order Rosenbrock scheme by providing parameter choices 79742faf41dSJed Brown 79842faf41dSJed Brown Not Collective, but the same schemes should be registered on all processes on which they will be used 79942faf41dSJed Brown 80042faf41dSJed Brown Input Parameters: 80142faf41dSJed Brown + name - identifier for method 80242faf41dSJed Brown . gamma - leading coefficient (diagonal entry) 80342faf41dSJed Brown . a2 - design parameter, see Table 7.2 of Hairer&Wanner 80442faf41dSJed Brown . a3 - design parameter or PETSC_DEFAULT to satisfy one of the order five conditions (Eq 7.22) 80542faf41dSJed Brown . b3 - design parameter, see Table 7.2 of Hairer&Wanner 806a2b725a8SWilliam Gropp - e4 - design parameter for embedded method, see coefficient E4 in ros4.f code from Hairer 80742faf41dSJed Brown 808bcf0153eSBarry Smith Level: developer 809bcf0153eSBarry Smith 81042faf41dSJed Brown Notes: 81142faf41dSJed Brown This routine encodes the design of fourth order Rosenbrock methods as described in Hairer and Wanner volume 2. 81242faf41dSJed Brown It is used here to implement several methods from the book and can be used to experiment with new methods. 81342faf41dSJed Brown It was written this way instead of by copying coefficients in order to provide better than double precision satisfaction of the order conditions. 81442faf41dSJed Brown 8151cc06b55SBarry Smith .seealso: [](ch_ts), `TSRosW`, `TSRosWRegister()` 81642faf41dSJed Brown @*/ 817d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRosWRegisterRos4(TSRosWType name, PetscReal gamma, PetscReal a2, PetscReal a3, PetscReal b3, PetscReal e4) 818d71ae5a4SJacob Faibussowitsch { 81942faf41dSJed Brown /* Declare numeric constants so they can be quad precision without being truncated at double */ 8209371c9d4SSatish 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; 82142faf41dSJed Brown PetscReal a4, a32, a42, a43, b1, b2, b4, beta2p, beta3p, beta4p, beta32, beta42, beta43, beta32beta2p, beta4jbetajp; 82242faf41dSJed Brown PetscReal A[4][4], Gamma[4][4], b[4], bm[4]; 82342faf41dSJed Brown PetscScalar M[3][3], rhs[3]; 82442faf41dSJed Brown 82542faf41dSJed Brown PetscFunctionBegin; 82642faf41dSJed Brown /* Step 1: choose Gamma (input) */ 82742faf41dSJed Brown /* Step 2: choose a2,a3,a4; b1,b2,b3,b4 to satisfy order conditions */ 82813bcc0bdSJacob Faibussowitsch if (a3 == (PetscReal)PETSC_DEFAULT) a3 = (one / five - a2 / four) / (one / four - a2 / three); /* Eq 7.22 */ 82942faf41dSJed Brown a4 = a3; /* consequence of 7.20 */ 83042faf41dSJed Brown 83142faf41dSJed Brown /* Solve order conditions 7.15a, 7.15c, 7.15e */ 8329371c9d4SSatish Balay M[0][0] = one; 8339371c9d4SSatish Balay M[0][1] = one; 8349371c9d4SSatish Balay M[0][2] = one; /* 7.15a */ 8359371c9d4SSatish Balay M[1][0] = 0.0; 8369371c9d4SSatish Balay M[1][1] = a2 * a2; 8379371c9d4SSatish Balay M[1][2] = a4 * a4; /* 7.15c */ 8389371c9d4SSatish Balay M[2][0] = 0.0; 8399371c9d4SSatish Balay M[2][1] = a2 * a2 * a2; 8409371c9d4SSatish Balay M[2][2] = a4 * a4 * a4; /* 7.15e */ 84142faf41dSJed Brown rhs[0] = one - b3; 84242faf41dSJed Brown rhs[1] = one / three - a3 * a3 * b3; 84342faf41dSJed Brown rhs[2] = one / four - a3 * a3 * a3 * b3; 8449566063dSJacob Faibussowitsch PetscCall(PetscKernel_A_gets_inverse_A_3(&M[0][0], 0, PETSC_FALSE, NULL)); 84542faf41dSJed Brown b1 = PetscRealPart(M[0][0] * rhs[0] + M[0][1] * rhs[1] + M[0][2] * rhs[2]); 84642faf41dSJed Brown b2 = PetscRealPart(M[1][0] * rhs[0] + M[1][1] * rhs[1] + M[1][2] * rhs[2]); 84742faf41dSJed Brown b4 = PetscRealPart(M[2][0] * rhs[0] + M[2][1] * rhs[1] + M[2][2] * rhs[2]); 84842faf41dSJed Brown 84942faf41dSJed Brown /* Step 3 */ 85042faf41dSJed Brown beta43 = (p56 - a2 * p43) / (b4 * a3 * a3 * (a3 - a2)); /* 7.21 */ 85142faf41dSJed Brown beta32beta2p = p44 / (b4 * beta43); /* 7.15h */ 85242faf41dSJed Brown beta4jbetajp = (p32 - b3 * beta32beta2p) / b4; 8539371c9d4SSatish Balay M[0][0] = b2; 8549371c9d4SSatish Balay M[0][1] = b3; 8559371c9d4SSatish Balay M[0][2] = b4; 8569371c9d4SSatish Balay M[1][0] = a4 * a4 * beta32beta2p - a3 * a3 * beta4jbetajp; 8579371c9d4SSatish Balay M[1][1] = a2 * a2 * beta4jbetajp; 8589371c9d4SSatish Balay M[1][2] = -a2 * a2 * beta32beta2p; 8599371c9d4SSatish Balay M[2][0] = b4 * beta43 * a3 * a3 - p43; 8609371c9d4SSatish Balay M[2][1] = -b4 * beta43 * a2 * a2; 8619371c9d4SSatish Balay M[2][2] = 0; 8629371c9d4SSatish Balay rhs[0] = one / two - gamma; 8639371c9d4SSatish Balay rhs[1] = 0; 8649371c9d4SSatish Balay rhs[2] = -a2 * a2 * p32; 8659566063dSJacob Faibussowitsch PetscCall(PetscKernel_A_gets_inverse_A_3(&M[0][0], 0, PETSC_FALSE, NULL)); 86642faf41dSJed Brown beta2p = PetscRealPart(M[0][0] * rhs[0] + M[0][1] * rhs[1] + M[0][2] * rhs[2]); 86742faf41dSJed Brown beta3p = PetscRealPart(M[1][0] * rhs[0] + M[1][1] * rhs[1] + M[1][2] * rhs[2]); 86842faf41dSJed Brown beta4p = PetscRealPart(M[2][0] * rhs[0] + M[2][1] * rhs[1] + M[2][2] * rhs[2]); 86942faf41dSJed Brown 87042faf41dSJed Brown /* Step 4: back-substitute */ 87142faf41dSJed Brown beta32 = beta32beta2p / beta2p; 87242faf41dSJed Brown beta42 = (beta4jbetajp - beta43 * beta3p) / beta2p; 87342faf41dSJed Brown 87442faf41dSJed Brown /* Step 5: 7.15f and 7.20, then 7.16 */ 87542faf41dSJed Brown a43 = 0; 87642faf41dSJed Brown a32 = p42 / (b3 * a3 * beta2p + b4 * a4 * beta2p); 87742faf41dSJed Brown a42 = a32; 87842faf41dSJed Brown 8799371c9d4SSatish Balay A[0][0] = 0; 8809371c9d4SSatish Balay A[0][1] = 0; 8819371c9d4SSatish Balay A[0][2] = 0; 8829371c9d4SSatish Balay A[0][3] = 0; 8839371c9d4SSatish Balay A[1][0] = a2; 8849371c9d4SSatish Balay A[1][1] = 0; 8859371c9d4SSatish Balay A[1][2] = 0; 8869371c9d4SSatish Balay A[1][3] = 0; 8879371c9d4SSatish Balay A[2][0] = a3 - a32; 8889371c9d4SSatish Balay A[2][1] = a32; 8899371c9d4SSatish Balay A[2][2] = 0; 8909371c9d4SSatish Balay A[2][3] = 0; 8919371c9d4SSatish Balay A[3][0] = a4 - a43 - a42; 8929371c9d4SSatish Balay A[3][1] = a42; 8939371c9d4SSatish Balay A[3][2] = a43; 8949371c9d4SSatish Balay A[3][3] = 0; 8959371c9d4SSatish Balay Gamma[0][0] = gamma; 8969371c9d4SSatish Balay Gamma[0][1] = 0; 8979371c9d4SSatish Balay Gamma[0][2] = 0; 8989371c9d4SSatish Balay Gamma[0][3] = 0; 8999371c9d4SSatish Balay Gamma[1][0] = beta2p - A[1][0]; 9009371c9d4SSatish Balay Gamma[1][1] = gamma; 9019371c9d4SSatish Balay Gamma[1][2] = 0; 9029371c9d4SSatish Balay Gamma[1][3] = 0; 9039371c9d4SSatish Balay Gamma[2][0] = beta3p - beta32 - A[2][0]; 9049371c9d4SSatish Balay Gamma[2][1] = beta32 - A[2][1]; 9059371c9d4SSatish Balay Gamma[2][2] = gamma; 9069371c9d4SSatish Balay Gamma[2][3] = 0; 9079371c9d4SSatish Balay Gamma[3][0] = beta4p - beta42 - beta43 - A[3][0]; 9089371c9d4SSatish Balay Gamma[3][1] = beta42 - A[3][1]; 9099371c9d4SSatish Balay Gamma[3][2] = beta43 - A[3][2]; 9109371c9d4SSatish Balay Gamma[3][3] = gamma; 9119371c9d4SSatish Balay b[0] = b1; 9129371c9d4SSatish Balay b[1] = b2; 9139371c9d4SSatish Balay b[2] = b3; 9149371c9d4SSatish Balay b[3] = b4; 91542faf41dSJed Brown 91642faf41dSJed Brown /* Construct embedded formula using given e4. We are solving Equation 7.18. */ 91742faf41dSJed Brown bm[3] = b[3] - e4 * gamma; /* using definition of E4 */ 91842faf41dSJed Brown bm[2] = (p32 - beta4jbetajp * bm[3]) / (beta32 * beta2p); /* fourth row of 7.18 */ 91942faf41dSJed Brown bm[1] = (one / two - gamma - beta3p * bm[2] - beta4p * bm[3]) / beta2p; /* second row */ 92042faf41dSJed Brown bm[0] = one - bm[1] - bm[2] - bm[3]; /* first row */ 92142faf41dSJed Brown 92242faf41dSJed Brown { 92342faf41dSJed Brown const PetscReal misfit = a2 * a2 * bm[1] + a3 * a3 * bm[2] + a4 * a4 * bm[3] - one / three; 9243c633725SBarry Smith PetscCheck(PetscAbs(misfit) <= PETSC_SMALL, PETSC_COMM_SELF, PETSC_ERR_SUP, "Assumptions violated, could not construct a third order embedded method"); 92542faf41dSJed Brown } 9269566063dSJacob Faibussowitsch PetscCall(TSRosWRegister(name, 4, 4, &A[0][0], &Gamma[0][0], b, bm, 0, NULL)); 9273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 92842faf41dSJed Brown } 92942faf41dSJed Brown 9301c3436cfSJed Brown /* 9311c3436cfSJed Brown The step completion formula is 9321c3436cfSJed Brown 9331c3436cfSJed Brown x1 = x0 + b^T Y 9341c3436cfSJed Brown 9351c3436cfSJed Brown where Y is the multi-vector of stages corrections. This function can be called before or after ts->vec_sol has been 9361c3436cfSJed Brown updated. Suppose we have a completion formula b and an embedded formula be of different order. We can write 9371c3436cfSJed Brown 9381c3436cfSJed Brown x1e = x0 + be^T Y 9391c3436cfSJed Brown = x1 - b^T Y + be^T Y 9401c3436cfSJed Brown = x1 + (be - b)^T Y 9411c3436cfSJed Brown 9421c3436cfSJed Brown so we can evaluate the method of different order even after the step has been optimistically completed. 9431c3436cfSJed Brown */ 944d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSEvaluateStep_RosW(TS ts, PetscInt order, Vec U, PetscBool *done) 945d71ae5a4SJacob Faibussowitsch { 9461c3436cfSJed Brown TS_RosW *ros = (TS_RosW *)ts->data; 9471c3436cfSJed Brown RosWTableau tab = ros->tableau; 9481c3436cfSJed Brown PetscScalar *w = ros->work; 9491c3436cfSJed Brown PetscInt i; 9501c3436cfSJed Brown 9511c3436cfSJed Brown PetscFunctionBegin; 9521c3436cfSJed Brown if (order == tab->order) { 953108c343cSJed Brown if (ros->status == TS_STEP_INCOMPLETE) { /* Use standard completion formula */ 9549566063dSJacob Faibussowitsch PetscCall(VecCopy(ts->vec_sol, U)); 955de19f811SJed Brown for (i = 0; i < tab->s; i++) w[i] = tab->bt[i]; 9569566063dSJacob Faibussowitsch PetscCall(VecMAXPY(U, tab->s, w, ros->Y)); 9579566063dSJacob Faibussowitsch } else PetscCall(VecCopy(ts->vec_sol, U)); 9581c3436cfSJed Brown if (done) *done = PETSC_TRUE; 9593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9601c3436cfSJed Brown } else if (order == tab->order - 1) { 9611c3436cfSJed Brown if (!tab->bembedt) goto unavailable; 962108c343cSJed Brown if (ros->status == TS_STEP_INCOMPLETE) { /* Use embedded completion formula */ 9639566063dSJacob Faibussowitsch PetscCall(VecCopy(ts->vec_sol, U)); 964de19f811SJed Brown for (i = 0; i < tab->s; i++) w[i] = tab->bembedt[i]; 9659566063dSJacob Faibussowitsch PetscCall(VecMAXPY(U, tab->s, w, ros->Y)); 966108c343cSJed Brown } else { /* Use rollback-and-recomplete formula (bembedt - bt) */ 967108c343cSJed Brown for (i = 0; i < tab->s; i++) w[i] = tab->bembedt[i] - tab->bt[i]; 9689566063dSJacob Faibussowitsch PetscCall(VecCopy(ts->vec_sol, U)); 9699566063dSJacob Faibussowitsch PetscCall(VecMAXPY(U, tab->s, w, ros->Y)); 9701c3436cfSJed Brown } 9711c3436cfSJed Brown if (done) *done = PETSC_TRUE; 9723ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9731c3436cfSJed Brown } 9741c3436cfSJed Brown unavailable: 9751c3436cfSJed Brown if (done) *done = PETSC_FALSE; 9769371c9d4SSatish Balay else 9779371c9d4SSatish 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, 9789371c9d4SSatish Balay tab->order, order); 9793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9801c3436cfSJed Brown } 9811c3436cfSJed Brown 982d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSStep_RosW(TS ts) 983d71ae5a4SJacob Faibussowitsch { 98461692a83SJed Brown TS_RosW *ros = (TS_RosW *)ts->data; 98561692a83SJed Brown RosWTableau tab = ros->tableau; 986e27a552bSJed Brown const PetscInt s = tab->s; 9871c3436cfSJed Brown const PetscReal *At = tab->At, *Gamma = tab->Gamma, *ASum = tab->ASum, *GammaInv = tab->GammaInv; 9880feba352SEmil Constantinescu const PetscReal *GammaExplicitCorr = tab->GammaExplicitCorr; 989c17803e7SJed Brown const PetscBool *GammaZeroDiag = tab->GammaZeroDiag; 99061692a83SJed Brown PetscScalar *w = ros->work; 9917d4bf2deSEmil Constantinescu Vec *Y = ros->Y, Ydot = ros->Ydot, Zdot = ros->Zdot, Zstage = ros->Zstage; 992e27a552bSJed Brown SNES snes; 9931c3436cfSJed Brown TSAdapt adapt; 994fecfb714SLisandro Dalcin PetscInt i, j, its, lits; 995be5899b3SLisandro Dalcin PetscInt rejections = 0; 996b39943a6SLisandro Dalcin PetscBool stageok, accept = PETSC_TRUE; 997b39943a6SLisandro Dalcin PetscReal next_time_step = ts->time_step; 998f7f07198SBarry Smith PetscInt lag; 999e27a552bSJed Brown 1000e27a552bSJed Brown PetscFunctionBegin; 100148a46eb9SPierre Jolivet if (!ts->steprollback) PetscCall(VecCopy(ts->vec_sol, ros->vec_sol_prev)); 1002e27a552bSJed Brown 1003b39943a6SLisandro Dalcin ros->status = TS_STEP_INCOMPLETE; 1004b39943a6SLisandro Dalcin while (!ts->reason && ros->status != TS_STEP_COMPLETE) { 10051c3436cfSJed Brown const PetscReal h = ts->time_step; 1006e27a552bSJed Brown for (i = 0; i < s; i++) { 10071c3436cfSJed Brown ros->stage_time = ts->ptime + h * ASum[i]; 10089566063dSJacob Faibussowitsch PetscCall(TSPreStage(ts, ros->stage_time)); 1009c17803e7SJed Brown if (GammaZeroDiag[i]) { 1010c17803e7SJed Brown ros->stage_explicit = PETSC_TRUE; 1011b296d7d5SJed Brown ros->scoeff = 1.; 1012c17803e7SJed Brown } else { 1013c17803e7SJed Brown ros->stage_explicit = PETSC_FALSE; 1014b296d7d5SJed Brown ros->scoeff = 1. / Gamma[i * s + i]; 1015fd96d5b0SEmil Constantinescu } 101661692a83SJed Brown 10179566063dSJacob Faibussowitsch PetscCall(VecCopy(ts->vec_sol, Zstage)); 1018de19f811SJed Brown for (j = 0; j < i; j++) w[j] = At[i * s + j]; 10199566063dSJacob Faibussowitsch PetscCall(VecMAXPY(Zstage, i, w, Y)); 102061692a83SJed Brown 102161692a83SJed Brown for (j = 0; j < i; j++) w[j] = 1. / h * GammaInv[i * s + j]; 10229566063dSJacob Faibussowitsch PetscCall(VecZeroEntries(Zdot)); 10239566063dSJacob Faibussowitsch PetscCall(VecMAXPY(Zdot, i, w, Y)); 102461692a83SJed Brown 1025e27a552bSJed Brown /* Initial guess taken from last stage */ 10269566063dSJacob Faibussowitsch PetscCall(VecZeroEntries(Y[i])); 102761692a83SJed Brown 10287d4bf2deSEmil Constantinescu if (!ros->stage_explicit) { 10299566063dSJacob Faibussowitsch PetscCall(TSGetSNES(ts, &snes)); 103061692a83SJed Brown if (!ros->recompute_jacobian && !i) { 10319566063dSJacob Faibussowitsch PetscCall(SNESGetLagJacobian(snes, &lag)); 10326aad120cSJose E. Roman if (lag == 1) { /* use did not set a nontrivial lag, so lag over all stages */ 10339566063dSJacob Faibussowitsch PetscCall(SNESSetLagJacobian(snes, -2)); /* Recompute the Jacobian on this solve, but not again for the rest of the stages */ 1034f7f07198SBarry Smith } 103561692a83SJed Brown } 10369566063dSJacob Faibussowitsch PetscCall(SNESSolve(snes, NULL, Y[i])); 10379371c9d4SSatish 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 */ } 10389566063dSJacob Faibussowitsch PetscCall(SNESGetIterationNumber(snes, &its)); 10399566063dSJacob Faibussowitsch PetscCall(SNESGetLinearSolveIterations(snes, &lits)); 10409371c9d4SSatish Balay ts->snes_its += its; 10419371c9d4SSatish Balay ts->ksp_its += lits; 10427d4bf2deSEmil Constantinescu } else { 10431ce71dffSSatish Balay Mat J, Jp; 10449566063dSJacob Faibussowitsch PetscCall(VecZeroEntries(Ydot)); /* Evaluate Y[i]=G(t,Ydot=0,Zstage) */ 10459566063dSJacob Faibussowitsch PetscCall(TSComputeIFunction(ts, ros->stage_time, Zstage, Ydot, Y[i], PETSC_FALSE)); 10469566063dSJacob Faibussowitsch PetscCall(VecScale(Y[i], -1.0)); 10479566063dSJacob Faibussowitsch PetscCall(VecAXPY(Y[i], -1.0, Zdot)); /*Y[i] = F(Zstage)-Zdot[=GammaInv*Y]*/ 10480feba352SEmil Constantinescu 10499566063dSJacob Faibussowitsch PetscCall(VecZeroEntries(Zstage)); /* Zstage = GammaExplicitCorr[i,j] * Y[j] */ 10500feba352SEmil Constantinescu for (j = 0; j < i; j++) w[j] = GammaExplicitCorr[i * s + j]; 10519566063dSJacob Faibussowitsch PetscCall(VecMAXPY(Zstage, i, w, Y)); 1052fecfb714SLisandro Dalcin 1053fecfb714SLisandro Dalcin /* Y[i] = Y[i] + Jac*Zstage[=Jac*GammaExplicitCorr[i,j] * Y[j]] */ 10549566063dSJacob Faibussowitsch PetscCall(TSGetIJacobian(ts, &J, &Jp, NULL, NULL)); 10559566063dSJacob Faibussowitsch PetscCall(TSComputeIJacobian(ts, ros->stage_time, ts->vec_sol, Ydot, 0, J, Jp, PETSC_FALSE)); 10569566063dSJacob Faibussowitsch PetscCall(MatMult(J, Zstage, Zdot)); 10579566063dSJacob Faibussowitsch PetscCall(VecAXPY(Y[i], -1.0, Zdot)); 10585ef26d82SJed Brown ts->ksp_its += 1; 1059fecfb714SLisandro Dalcin 10609566063dSJacob Faibussowitsch PetscCall(VecScale(Y[i], h)); 10617d4bf2deSEmil Constantinescu } 10629566063dSJacob Faibussowitsch PetscCall(TSPostStage(ts, ros->stage_time, i, Y)); 10639566063dSJacob Faibussowitsch PetscCall(TSGetAdapt(ts, &adapt)); 10649566063dSJacob Faibussowitsch PetscCall(TSAdaptCheckStage(adapt, ts, ros->stage_time, Y[i], &stageok)); 1065fecfb714SLisandro Dalcin if (!stageok) goto reject_step; 1066e27a552bSJed Brown } 1067e27a552bSJed Brown 1068b39943a6SLisandro Dalcin ros->status = TS_STEP_INCOMPLETE; 10699566063dSJacob Faibussowitsch PetscCall(TSEvaluateStep_RosW(ts, tab->order, ts->vec_sol, NULL)); 1070b39943a6SLisandro Dalcin ros->status = TS_STEP_PENDING; 10719566063dSJacob Faibussowitsch PetscCall(TSGetAdapt(ts, &adapt)); 10729566063dSJacob Faibussowitsch PetscCall(TSAdaptCandidatesClear(adapt)); 10739566063dSJacob Faibussowitsch PetscCall(TSAdaptCandidateAdd(adapt, tab->name, tab->order, 1, tab->ccfl, (PetscReal)tab->s, PETSC_TRUE)); 10749566063dSJacob Faibussowitsch PetscCall(TSAdaptChoose(adapt, ts, ts->time_step, NULL, &next_time_step, &accept)); 1075b39943a6SLisandro Dalcin ros->status = accept ? TS_STEP_COMPLETE : TS_STEP_INCOMPLETE; 1076b39943a6SLisandro Dalcin if (!accept) { /* Roll back the current step */ 1077*c61711c8SStefano Zampini PetscCall(VecCopy(ts->vec_sol0, ts->vec_sol)); 1078be5899b3SLisandro Dalcin ts->time_step = next_time_step; 1079be5899b3SLisandro Dalcin goto reject_step; 1080b39943a6SLisandro Dalcin } 1081b39943a6SLisandro Dalcin 1082e27a552bSJed Brown ts->ptime += ts->time_step; 1083cdbf8f93SLisandro Dalcin ts->time_step = next_time_step; 10841c3436cfSJed Brown break; 1085b39943a6SLisandro Dalcin 1086b39943a6SLisandro Dalcin reject_step: 10879371c9d4SSatish Balay ts->reject++; 10889371c9d4SSatish Balay accept = PETSC_FALSE; 1089be5899b3SLisandro Dalcin if (!ts->reason && ++rejections > ts->max_reject && ts->max_reject >= 0) { 1090b39943a6SLisandro Dalcin ts->reason = TS_DIVERGED_STEP_REJECTED; 109163a3b9bcSJacob Faibussowitsch PetscCall(PetscInfo(ts, "Step=%" PetscInt_FMT ", step rejections %" PetscInt_FMT " greater than current TS allowed, stopping solve\n", ts->steps, rejections)); 10921c3436cfSJed Brown } 10931c3436cfSJed Brown } 10943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1095e27a552bSJed Brown } 1096e27a552bSJed Brown 1097d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSInterpolate_RosW(TS ts, PetscReal itime, Vec U) 1098d71ae5a4SJacob Faibussowitsch { 109961692a83SJed Brown TS_RosW *ros = (TS_RosW *)ts->data; 1100f4aed992SEmil Constantinescu PetscInt s = ros->tableau->s, pinterp = ros->tableau->pinterp, i, j; 1101f4aed992SEmil Constantinescu PetscReal h; 1102f4aed992SEmil Constantinescu PetscReal tt, t; 1103f4aed992SEmil Constantinescu PetscScalar *bt; 1104f4aed992SEmil Constantinescu const PetscReal *Bt = ros->tableau->binterpt; 1105f4aed992SEmil Constantinescu const PetscReal *GammaInv = ros->tableau->GammaInv; 1106f4aed992SEmil Constantinescu PetscScalar *w = ros->work; 1107f4aed992SEmil Constantinescu Vec *Y = ros->Y; 1108e27a552bSJed Brown 1109e27a552bSJed Brown PetscFunctionBegin; 11103c633725SBarry Smith PetscCheck(Bt, PetscObjectComm((PetscObject)ts), PETSC_ERR_SUP, "TSRosW %s does not have an interpolation formula", ros->tableau->name); 1111f4aed992SEmil Constantinescu 1112f4aed992SEmil Constantinescu switch (ros->status) { 1113f4aed992SEmil Constantinescu case TS_STEP_INCOMPLETE: 1114f4aed992SEmil Constantinescu case TS_STEP_PENDING: 1115f4aed992SEmil Constantinescu h = ts->time_step; 1116f4aed992SEmil Constantinescu t = (itime - ts->ptime) / h; 1117f4aed992SEmil Constantinescu break; 1118f4aed992SEmil Constantinescu case TS_STEP_COMPLETE: 1119be5899b3SLisandro Dalcin h = ts->ptime - ts->ptime_prev; 1120f4aed992SEmil Constantinescu t = (itime - ts->ptime) / h + 1; /* In the interval [0,1] */ 1121f4aed992SEmil Constantinescu break; 1122d71ae5a4SJacob Faibussowitsch default: 1123d71ae5a4SJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)ts), PETSC_ERR_PLIB, "Invalid TSStepStatus"); 1124f4aed992SEmil Constantinescu } 11259566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(s, &bt)); 1126f4aed992SEmil Constantinescu for (i = 0; i < s; i++) bt[i] = 0; 1127f4aed992SEmil Constantinescu for (j = 0, tt = t; j < pinterp; j++, tt *= t) { 1128ad540459SPierre Jolivet for (i = 0; i < s; i++) bt[i] += Bt[i * pinterp + j] * tt; 1129f4aed992SEmil Constantinescu } 1130f4aed992SEmil Constantinescu 1131f4aed992SEmil Constantinescu /* y(t+tt*h) = y(t) + Sum bt(tt) * GammaInv * Ydot */ 1132f9c1d6abSBarry Smith /* U <- 0*/ 11339566063dSJacob Faibussowitsch PetscCall(VecZeroEntries(U)); 1134f9c1d6abSBarry Smith /* U <- Sum bt_i * GammaInv(i,1:i) * Y(1:i) */ 11353ca35412SEmil Constantinescu for (j = 0; j < s; j++) w[j] = 0; 11363ca35412SEmil Constantinescu for (j = 0; j < s; j++) { 1137ad540459SPierre Jolivet for (i = j; i < s; i++) w[j] += bt[i] * GammaInv[i * s + j]; 11383ca35412SEmil Constantinescu } 11399566063dSJacob Faibussowitsch PetscCall(VecMAXPY(U, i, w, Y)); 1140be5899b3SLisandro Dalcin /* U <- y(t) + U */ 11419566063dSJacob Faibussowitsch PetscCall(VecAXPY(U, 1, ros->vec_sol_prev)); 1142f4aed992SEmil Constantinescu 11439566063dSJacob Faibussowitsch PetscCall(PetscFree(bt)); 11443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1145e27a552bSJed Brown } 1146e27a552bSJed Brown 1147e27a552bSJed Brown /*------------------------------------------------------------*/ 1148b39943a6SLisandro Dalcin 1149d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSRosWTableauReset(TS ts) 1150d71ae5a4SJacob Faibussowitsch { 1151b39943a6SLisandro Dalcin TS_RosW *ros = (TS_RosW *)ts->data; 1152b39943a6SLisandro Dalcin RosWTableau tab = ros->tableau; 1153b39943a6SLisandro Dalcin 1154b39943a6SLisandro Dalcin PetscFunctionBegin; 11553ba16761SJacob Faibussowitsch if (!tab) PetscFunctionReturn(PETSC_SUCCESS); 11569566063dSJacob Faibussowitsch PetscCall(VecDestroyVecs(tab->s, &ros->Y)); 11579566063dSJacob Faibussowitsch PetscCall(PetscFree(ros->work)); 11583ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1159b39943a6SLisandro Dalcin } 1160b39943a6SLisandro Dalcin 1161d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSReset_RosW(TS ts) 1162d71ae5a4SJacob Faibussowitsch { 116361692a83SJed Brown TS_RosW *ros = (TS_RosW *)ts->data; 1164e27a552bSJed Brown 1165e27a552bSJed Brown PetscFunctionBegin; 11669566063dSJacob Faibussowitsch PetscCall(TSRosWTableauReset(ts)); 11679566063dSJacob Faibussowitsch PetscCall(VecDestroy(&ros->Ydot)); 11689566063dSJacob Faibussowitsch PetscCall(VecDestroy(&ros->Ystage)); 11699566063dSJacob Faibussowitsch PetscCall(VecDestroy(&ros->Zdot)); 11709566063dSJacob Faibussowitsch PetscCall(VecDestroy(&ros->Zstage)); 11719566063dSJacob Faibussowitsch PetscCall(VecDestroy(&ros->vec_sol_prev)); 11723ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1173e27a552bSJed Brown } 1174e27a552bSJed Brown 1175d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSRosWGetVecs(TS ts, DM dm, Vec *Ydot, Vec *Zdot, Vec *Ystage, Vec *Zstage) 1176d71ae5a4SJacob Faibussowitsch { 1177d5e6173cSPeter Brune TS_RosW *rw = (TS_RosW *)ts->data; 1178d5e6173cSPeter Brune 1179d5e6173cSPeter Brune PetscFunctionBegin; 1180d5e6173cSPeter Brune if (Ydot) { 1181d5e6173cSPeter Brune if (dm && dm != ts->dm) { 11829566063dSJacob Faibussowitsch PetscCall(DMGetNamedGlobalVector(dm, "TSRosW_Ydot", Ydot)); 1183d5e6173cSPeter Brune } else *Ydot = rw->Ydot; 1184d5e6173cSPeter Brune } 1185d5e6173cSPeter Brune if (Zdot) { 1186d5e6173cSPeter Brune if (dm && dm != ts->dm) { 11879566063dSJacob Faibussowitsch PetscCall(DMGetNamedGlobalVector(dm, "TSRosW_Zdot", Zdot)); 1188d5e6173cSPeter Brune } else *Zdot = rw->Zdot; 1189d5e6173cSPeter Brune } 1190d5e6173cSPeter Brune if (Ystage) { 1191d5e6173cSPeter Brune if (dm && dm != ts->dm) { 11929566063dSJacob Faibussowitsch PetscCall(DMGetNamedGlobalVector(dm, "TSRosW_Ystage", Ystage)); 1193d5e6173cSPeter Brune } else *Ystage = rw->Ystage; 1194d5e6173cSPeter Brune } 1195d5e6173cSPeter Brune if (Zstage) { 1196d5e6173cSPeter Brune if (dm && dm != ts->dm) { 11979566063dSJacob Faibussowitsch PetscCall(DMGetNamedGlobalVector(dm, "TSRosW_Zstage", Zstage)); 1198d5e6173cSPeter Brune } else *Zstage = rw->Zstage; 1199d5e6173cSPeter Brune } 12003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1201d5e6173cSPeter Brune } 1202d5e6173cSPeter Brune 1203d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSRosWRestoreVecs(TS ts, DM dm, Vec *Ydot, Vec *Zdot, Vec *Ystage, Vec *Zstage) 1204d71ae5a4SJacob Faibussowitsch { 1205d5e6173cSPeter Brune PetscFunctionBegin; 1206d5e6173cSPeter Brune if (Ydot) { 120748a46eb9SPierre Jolivet if (dm && dm != ts->dm) PetscCall(DMRestoreNamedGlobalVector(dm, "TSRosW_Ydot", Ydot)); 1208d5e6173cSPeter Brune } 1209d5e6173cSPeter Brune if (Zdot) { 121048a46eb9SPierre Jolivet if (dm && dm != ts->dm) PetscCall(DMRestoreNamedGlobalVector(dm, "TSRosW_Zdot", Zdot)); 1211d5e6173cSPeter Brune } 1212d5e6173cSPeter Brune if (Ystage) { 121348a46eb9SPierre Jolivet if (dm && dm != ts->dm) PetscCall(DMRestoreNamedGlobalVector(dm, "TSRosW_Ystage", Ystage)); 1214d5e6173cSPeter Brune } 1215d5e6173cSPeter Brune if (Zstage) { 121648a46eb9SPierre Jolivet if (dm && dm != ts->dm) PetscCall(DMRestoreNamedGlobalVector(dm, "TSRosW_Zstage", Zstage)); 1217d5e6173cSPeter Brune } 12183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1219d5e6173cSPeter Brune } 1220d5e6173cSPeter Brune 1221d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMCoarsenHook_TSRosW(DM fine, DM coarse, void *ctx) 1222d71ae5a4SJacob Faibussowitsch { 1223d5e6173cSPeter Brune PetscFunctionBegin; 12243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1225d5e6173cSPeter Brune } 1226d5e6173cSPeter Brune 1227d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMRestrictHook_TSRosW(DM fine, Mat restrct, Vec rscale, Mat inject, DM coarse, void *ctx) 1228d71ae5a4SJacob Faibussowitsch { 1229d5e6173cSPeter Brune TS ts = (TS)ctx; 1230d5e6173cSPeter Brune Vec Ydot, Zdot, Ystage, Zstage; 1231d5e6173cSPeter Brune Vec Ydotc, Zdotc, Ystagec, Zstagec; 1232d5e6173cSPeter Brune 1233d5e6173cSPeter Brune PetscFunctionBegin; 12349566063dSJacob Faibussowitsch PetscCall(TSRosWGetVecs(ts, fine, &Ydot, &Ystage, &Zdot, &Zstage)); 12359566063dSJacob Faibussowitsch PetscCall(TSRosWGetVecs(ts, coarse, &Ydotc, &Ystagec, &Zdotc, &Zstagec)); 12369566063dSJacob Faibussowitsch PetscCall(MatRestrict(restrct, Ydot, Ydotc)); 12379566063dSJacob Faibussowitsch PetscCall(VecPointwiseMult(Ydotc, rscale, Ydotc)); 12389566063dSJacob Faibussowitsch PetscCall(MatRestrict(restrct, Ystage, Ystagec)); 12399566063dSJacob Faibussowitsch PetscCall(VecPointwiseMult(Ystagec, rscale, Ystagec)); 12409566063dSJacob Faibussowitsch PetscCall(MatRestrict(restrct, Zdot, Zdotc)); 12419566063dSJacob Faibussowitsch PetscCall(VecPointwiseMult(Zdotc, rscale, Zdotc)); 12429566063dSJacob Faibussowitsch PetscCall(MatRestrict(restrct, Zstage, Zstagec)); 12439566063dSJacob Faibussowitsch PetscCall(VecPointwiseMult(Zstagec, rscale, Zstagec)); 12449566063dSJacob Faibussowitsch PetscCall(TSRosWRestoreVecs(ts, fine, &Ydot, &Ystage, &Zdot, &Zstage)); 12459566063dSJacob Faibussowitsch PetscCall(TSRosWRestoreVecs(ts, coarse, &Ydotc, &Ystagec, &Zdotc, &Zstagec)); 12463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1247d5e6173cSPeter Brune } 1248d5e6173cSPeter Brune 1249d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMSubDomainHook_TSRosW(DM fine, DM coarse, void *ctx) 1250d71ae5a4SJacob Faibussowitsch { 1251258e1594SPeter Brune PetscFunctionBegin; 12523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1253258e1594SPeter Brune } 1254258e1594SPeter Brune 1255d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMSubDomainRestrictHook_TSRosW(DM dm, VecScatter gscat, VecScatter lscat, DM subdm, void *ctx) 1256d71ae5a4SJacob Faibussowitsch { 1257258e1594SPeter Brune TS ts = (TS)ctx; 1258258e1594SPeter Brune Vec Ydot, Zdot, Ystage, Zstage; 1259258e1594SPeter Brune Vec Ydots, Zdots, Ystages, Zstages; 1260258e1594SPeter Brune 1261258e1594SPeter Brune PetscFunctionBegin; 12629566063dSJacob Faibussowitsch PetscCall(TSRosWGetVecs(ts, dm, &Ydot, &Ystage, &Zdot, &Zstage)); 12639566063dSJacob Faibussowitsch PetscCall(TSRosWGetVecs(ts, subdm, &Ydots, &Ystages, &Zdots, &Zstages)); 1264258e1594SPeter Brune 12659566063dSJacob Faibussowitsch PetscCall(VecScatterBegin(gscat, Ydot, Ydots, INSERT_VALUES, SCATTER_FORWARD)); 12669566063dSJacob Faibussowitsch PetscCall(VecScatterEnd(gscat, Ydot, Ydots, INSERT_VALUES, SCATTER_FORWARD)); 1267258e1594SPeter Brune 12689566063dSJacob Faibussowitsch PetscCall(VecScatterBegin(gscat, Ystage, Ystages, INSERT_VALUES, SCATTER_FORWARD)); 12699566063dSJacob Faibussowitsch PetscCall(VecScatterEnd(gscat, Ystage, Ystages, INSERT_VALUES, SCATTER_FORWARD)); 1270258e1594SPeter Brune 12719566063dSJacob Faibussowitsch PetscCall(VecScatterBegin(gscat, Zdot, Zdots, INSERT_VALUES, SCATTER_FORWARD)); 12729566063dSJacob Faibussowitsch PetscCall(VecScatterEnd(gscat, Zdot, Zdots, INSERT_VALUES, SCATTER_FORWARD)); 1273258e1594SPeter Brune 12749566063dSJacob Faibussowitsch PetscCall(VecScatterBegin(gscat, Zstage, Zstages, INSERT_VALUES, SCATTER_FORWARD)); 12759566063dSJacob Faibussowitsch PetscCall(VecScatterEnd(gscat, Zstage, Zstages, INSERT_VALUES, SCATTER_FORWARD)); 1276258e1594SPeter Brune 12779566063dSJacob Faibussowitsch PetscCall(TSRosWRestoreVecs(ts, dm, &Ydot, &Ystage, &Zdot, &Zstage)); 12789566063dSJacob Faibussowitsch PetscCall(TSRosWRestoreVecs(ts, subdm, &Ydots, &Ystages, &Zdots, &Zstages)); 12793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1280258e1594SPeter Brune } 1281258e1594SPeter Brune 1282d71ae5a4SJacob Faibussowitsch static PetscErrorCode SNESTSFormFunction_RosW(SNES snes, Vec U, Vec F, TS ts) 1283d71ae5a4SJacob Faibussowitsch { 128461692a83SJed Brown TS_RosW *ros = (TS_RosW *)ts->data; 1285d5e6173cSPeter Brune Vec Ydot, Zdot, Ystage, Zstage; 1286b296d7d5SJed Brown PetscReal shift = ros->scoeff / ts->time_step; 1287d5e6173cSPeter Brune DM dm, dmsave; 1288e27a552bSJed Brown 1289e27a552bSJed Brown PetscFunctionBegin; 12909566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 12919566063dSJacob Faibussowitsch PetscCall(TSRosWGetVecs(ts, dm, &Ydot, &Zdot, &Ystage, &Zstage)); 12929566063dSJacob Faibussowitsch PetscCall(VecWAXPY(Ydot, shift, U, Zdot)); /* Ydot = shift*U + Zdot */ 12939566063dSJacob Faibussowitsch PetscCall(VecWAXPY(Ystage, 1.0, U, Zstage)); /* Ystage = U + Zstage */ 1294d5e6173cSPeter Brune dmsave = ts->dm; 1295d5e6173cSPeter Brune ts->dm = dm; 12969566063dSJacob Faibussowitsch PetscCall(TSComputeIFunction(ts, ros->stage_time, Ystage, Ydot, F, PETSC_FALSE)); 1297d5e6173cSPeter Brune ts->dm = dmsave; 12989566063dSJacob Faibussowitsch PetscCall(TSRosWRestoreVecs(ts, dm, &Ydot, &Zdot, &Ystage, &Zstage)); 12993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1300e27a552bSJed Brown } 1301e27a552bSJed Brown 1302d71ae5a4SJacob Faibussowitsch static PetscErrorCode SNESTSFormJacobian_RosW(SNES snes, Vec U, Mat A, Mat B, TS ts) 1303d71ae5a4SJacob Faibussowitsch { 130461692a83SJed Brown TS_RosW *ros = (TS_RosW *)ts->data; 1305d5e6173cSPeter Brune Vec Ydot, Zdot, Ystage, Zstage; 1306b296d7d5SJed Brown PetscReal shift = ros->scoeff / ts->time_step; 1307d5e6173cSPeter Brune DM dm, dmsave; 1308e27a552bSJed Brown 1309e27a552bSJed Brown PetscFunctionBegin; 131061692a83SJed Brown /* ros->Ydot and ros->Ystage have already been computed in SNESTSFormFunction_RosW (SNES guarantees this) */ 13119566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 13129566063dSJacob Faibussowitsch PetscCall(TSRosWGetVecs(ts, dm, &Ydot, &Zdot, &Ystage, &Zstage)); 1313d5e6173cSPeter Brune dmsave = ts->dm; 1314d5e6173cSPeter Brune ts->dm = dm; 13159566063dSJacob Faibussowitsch PetscCall(TSComputeIJacobian(ts, ros->stage_time, Ystage, Ydot, shift, A, B, PETSC_TRUE)); 1316d5e6173cSPeter Brune ts->dm = dmsave; 13179566063dSJacob Faibussowitsch PetscCall(TSRosWRestoreVecs(ts, dm, &Ydot, &Zdot, &Ystage, &Zstage)); 13183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1319e27a552bSJed Brown } 1320e27a552bSJed Brown 1321d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSRosWTableauSetUp(TS ts) 1322d71ae5a4SJacob Faibussowitsch { 1323b39943a6SLisandro Dalcin TS_RosW *ros = (TS_RosW *)ts->data; 1324b39943a6SLisandro Dalcin RosWTableau tab = ros->tableau; 1325b39943a6SLisandro Dalcin 1326b39943a6SLisandro Dalcin PetscFunctionBegin; 13279566063dSJacob Faibussowitsch PetscCall(VecDuplicateVecs(ts->vec_sol, tab->s, &ros->Y)); 13289566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(tab->s, &ros->work)); 13293ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1330b39943a6SLisandro Dalcin } 1331b39943a6SLisandro Dalcin 1332d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSSetUp_RosW(TS ts) 1333d71ae5a4SJacob Faibussowitsch { 133461692a83SJed Brown TS_RosW *ros = (TS_RosW *)ts->data; 1335d5e6173cSPeter Brune DM dm; 1336b39943a6SLisandro Dalcin SNES snes; 13378434afd1SBarry Smith TSRHSJacobianFn *rhsjacobian; 1338e27a552bSJed Brown 1339e27a552bSJed Brown PetscFunctionBegin; 13409566063dSJacob Faibussowitsch PetscCall(TSRosWTableauSetUp(ts)); 13419566063dSJacob Faibussowitsch PetscCall(VecDuplicate(ts->vec_sol, &ros->Ydot)); 13429566063dSJacob Faibussowitsch PetscCall(VecDuplicate(ts->vec_sol, &ros->Ystage)); 13439566063dSJacob Faibussowitsch PetscCall(VecDuplicate(ts->vec_sol, &ros->Zdot)); 13449566063dSJacob Faibussowitsch PetscCall(VecDuplicate(ts->vec_sol, &ros->Zstage)); 13459566063dSJacob Faibussowitsch PetscCall(VecDuplicate(ts->vec_sol, &ros->vec_sol_prev)); 13469566063dSJacob Faibussowitsch PetscCall(TSGetDM(ts, &dm)); 13479566063dSJacob Faibussowitsch PetscCall(DMCoarsenHookAdd(dm, DMCoarsenHook_TSRosW, DMRestrictHook_TSRosW, ts)); 13489566063dSJacob Faibussowitsch PetscCall(DMSubDomainHookAdd(dm, DMSubDomainHook_TSRosW, DMSubDomainRestrictHook_TSRosW, ts)); 1349b39943a6SLisandro Dalcin /* Rosenbrock methods are linearly implicit, so set that unless the user has specifically asked for something else */ 13509566063dSJacob Faibussowitsch PetscCall(TSGetSNES(ts, &snes)); 135148a46eb9SPierre Jolivet if (!((PetscObject)snes)->type_name) PetscCall(SNESSetType(snes, SNESKSPONLY)); 13529566063dSJacob Faibussowitsch PetscCall(DMTSGetRHSJacobian(dm, &rhsjacobian, NULL)); 1353a3ab5968SHong Zhang if (rhsjacobian == TSComputeRHSJacobianConstant) { 1354a3ab5968SHong Zhang Mat Amat, Pmat; 1355a3ab5968SHong Zhang 1356a3ab5968SHong Zhang /* Set the SNES matrix to be different from the RHS matrix because there is no way to reconstruct shift*M-J */ 13579566063dSJacob Faibussowitsch PetscCall(SNESGetJacobian(snes, &Amat, &Pmat, NULL, NULL)); 1358a3ab5968SHong Zhang if (Amat && Amat == ts->Arhs) { 1359a3ab5968SHong Zhang if (Amat == Pmat) { 13609566063dSJacob Faibussowitsch PetscCall(MatDuplicate(ts->Arhs, MAT_COPY_VALUES, &Amat)); 13619566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, Amat, Amat, NULL, NULL)); 1362a3ab5968SHong Zhang } else { 13639566063dSJacob Faibussowitsch PetscCall(MatDuplicate(ts->Arhs, MAT_COPY_VALUES, &Amat)); 13649566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, Amat, NULL, NULL, NULL)); 1365a3ab5968SHong Zhang if (Pmat && Pmat == ts->Brhs) { 13669566063dSJacob Faibussowitsch PetscCall(MatDuplicate(ts->Brhs, MAT_COPY_VALUES, &Pmat)); 13679566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, NULL, Pmat, NULL, NULL)); 13689566063dSJacob Faibussowitsch PetscCall(MatDestroy(&Pmat)); 1369a3ab5968SHong Zhang } 1370a3ab5968SHong Zhang } 13719566063dSJacob Faibussowitsch PetscCall(MatDestroy(&Amat)); 1372a3ab5968SHong Zhang } 1373a3ab5968SHong Zhang } 13743ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1375e27a552bSJed Brown } 1376e27a552bSJed Brown /*------------------------------------------------------------*/ 1377e27a552bSJed Brown 1378d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSSetFromOptions_RosW(TS ts, PetscOptionItems *PetscOptionsObject) 1379d71ae5a4SJacob Faibussowitsch { 138061692a83SJed Brown TS_RosW *ros = (TS_RosW *)ts->data; 1381b39943a6SLisandro Dalcin SNES snes; 1382e27a552bSJed Brown 1383e27a552bSJed Brown PetscFunctionBegin; 1384d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "RosW ODE solver options"); 1385e27a552bSJed Brown { 138661692a83SJed Brown RosWTableauLink link; 1387e27a552bSJed Brown PetscInt count, choice; 1388e27a552bSJed Brown PetscBool flg; 1389e27a552bSJed Brown const char **namelist; 139061692a83SJed Brown 1391fbccb6d4SPierre Jolivet for (link = RosWTableauList, count = 0; link; link = link->next, count++); 13929566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(count, (char ***)&namelist)); 139361692a83SJed Brown for (link = RosWTableauList, count = 0; link; link = link->next, count++) namelist[count] = link->tab.name; 13949566063dSJacob Faibussowitsch PetscCall(PetscOptionsEList("-ts_rosw_type", "Family of Rosenbrock-W method", "TSRosWSetType", (const char *const *)namelist, count, ros->tableau->name, &choice, &flg)); 13959566063dSJacob Faibussowitsch if (flg) PetscCall(TSRosWSetType(ts, namelist[choice])); 13969566063dSJacob Faibussowitsch PetscCall(PetscFree(namelist)); 139761692a83SJed Brown 13989566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-ts_rosw_recompute_jacobian", "Recompute the Jacobian at each stage", "TSRosWSetRecomputeJacobian", ros->recompute_jacobian, &ros->recompute_jacobian, NULL)); 1399b39943a6SLisandro Dalcin } 1400d0609cedSBarry Smith PetscOptionsHeadEnd(); 140161692a83SJed Brown /* Rosenbrock methods are linearly implicit, so set that unless the user has specifically asked for something else */ 14029566063dSJacob Faibussowitsch PetscCall(TSGetSNES(ts, &snes)); 140348a46eb9SPierre Jolivet if (!((PetscObject)snes)->type_name) PetscCall(SNESSetType(snes, SNESKSPONLY)); 14043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1405e27a552bSJed Brown } 1406e27a552bSJed Brown 1407d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSView_RosW(TS ts, PetscViewer viewer) 1408d71ae5a4SJacob Faibussowitsch { 140961692a83SJed Brown TS_RosW *ros = (TS_RosW *)ts->data; 1410e27a552bSJed Brown PetscBool iascii; 1411e27a552bSJed Brown 1412e27a552bSJed Brown PetscFunctionBegin; 14139566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 1414e27a552bSJed Brown if (iascii) { 14159c334d8fSLisandro Dalcin RosWTableau tab = ros->tableau; 141619fd82e9SBarry Smith TSRosWType rostype; 14179c334d8fSLisandro Dalcin char buf[512]; 1418e408995aSJed Brown PetscInt i; 1419e408995aSJed Brown PetscReal abscissa[512]; 14209566063dSJacob Faibussowitsch PetscCall(TSRosWGetType(ts, &rostype)); 14219566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Rosenbrock-W %s\n", rostype)); 14229566063dSJacob Faibussowitsch PetscCall(PetscFormatRealArray(buf, sizeof(buf), "% 8.6f", tab->s, tab->ASum)); 14239566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Abscissa of A = %s\n", buf)); 1424e408995aSJed Brown for (i = 0; i < tab->s; i++) abscissa[i] = tab->ASum[i] + tab->Gamma[i]; 14259566063dSJacob Faibussowitsch PetscCall(PetscFormatRealArray(buf, sizeof(buf), "% 8.6f", tab->s, abscissa)); 14269566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Abscissa of A+Gamma = %s\n", buf)); 1427e27a552bSJed Brown } 14283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1429e27a552bSJed Brown } 1430e27a552bSJed Brown 1431d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSLoad_RosW(TS ts, PetscViewer viewer) 1432d71ae5a4SJacob Faibussowitsch { 14339200755eSBarry Smith SNES snes; 14349c334d8fSLisandro Dalcin TSAdapt adapt; 14359200755eSBarry Smith 14369200755eSBarry Smith PetscFunctionBegin; 14379566063dSJacob Faibussowitsch PetscCall(TSGetAdapt(ts, &adapt)); 14389566063dSJacob Faibussowitsch PetscCall(TSAdaptLoad(adapt, viewer)); 14399566063dSJacob Faibussowitsch PetscCall(TSGetSNES(ts, &snes)); 14409566063dSJacob Faibussowitsch PetscCall(SNESLoad(snes, viewer)); 14419200755eSBarry Smith /* function and Jacobian context for SNES when used with TS is always ts object */ 14429566063dSJacob Faibussowitsch PetscCall(SNESSetFunction(snes, NULL, NULL, ts)); 14439566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, NULL, NULL, NULL, ts)); 14443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 14459200755eSBarry Smith } 14469200755eSBarry Smith 1447e27a552bSJed Brown /*@C 1448bcf0153eSBarry Smith TSRosWSetType - Set the type of Rosenbrock-W, `TSROSW`, scheme 1449e27a552bSJed Brown 145020f4b53cSBarry Smith Logically Collective 1451e27a552bSJed Brown 1452d8d19677SJose E. Roman Input Parameters: 1453e27a552bSJed Brown + ts - timestepping context 1454b92453a8SLisandro Dalcin - roswtype - type of Rosenbrock-W scheme 1455e27a552bSJed Brown 1456020d8f30SJed Brown Level: beginner 1457e27a552bSJed Brown 14581cc06b55SBarry Smith .seealso: [](ch_ts), `TSRosWGetType()`, `TSROSW`, `TSROSW2M`, `TSROSW2P`, `TSROSWRA3PW`, `TSROSWRA34PW2`, `TSROSWRODAS3`, `TSROSWSANDU3`, `TSROSWASSP3P3S1C`, `TSROSWLASSP3P4S2C`, `TSROSWLLSSP3P4S2C`, `TSROSWARK3` 1459e27a552bSJed Brown @*/ 1460d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRosWSetType(TS ts, TSRosWType roswtype) 1461d71ae5a4SJacob Faibussowitsch { 1462e27a552bSJed Brown PetscFunctionBegin; 1463e27a552bSJed Brown PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 14644f572ea9SToby Isaac PetscAssertPointer(roswtype, 2); 1465cac4c232SBarry Smith PetscTryMethod(ts, "TSRosWSetType_C", (TS, TSRosWType), (ts, roswtype)); 14663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1467e27a552bSJed Brown } 1468e27a552bSJed Brown 1469e27a552bSJed Brown /*@C 147061692a83SJed Brown TSRosWGetType - Get the type of Rosenbrock-W scheme 1471e27a552bSJed Brown 147220f4b53cSBarry Smith Logically Collective 1473e27a552bSJed Brown 1474e27a552bSJed Brown Input Parameter: 1475e27a552bSJed Brown . ts - timestepping context 1476e27a552bSJed Brown 1477e27a552bSJed Brown Output Parameter: 147861692a83SJed Brown . rostype - type of Rosenbrock-W scheme 1479e27a552bSJed Brown 1480e27a552bSJed Brown Level: intermediate 1481e27a552bSJed Brown 14821cc06b55SBarry Smith .seealso: [](ch_ts), `TSRosWType`, `TSRosWSetType()` 1483e27a552bSJed Brown @*/ 1484d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRosWGetType(TS ts, TSRosWType *rostype) 1485d71ae5a4SJacob Faibussowitsch { 1486e27a552bSJed Brown PetscFunctionBegin; 1487e27a552bSJed Brown PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 1488cac4c232SBarry Smith PetscUseMethod(ts, "TSRosWGetType_C", (TS, TSRosWType *), (ts, rostype)); 14893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1490e27a552bSJed Brown } 1491e27a552bSJed Brown 1492e27a552bSJed Brown /*@C 149361692a83SJed Brown TSRosWSetRecomputeJacobian - Set whether to recompute the Jacobian at each stage. The default is to update the Jacobian once per step. 1494e27a552bSJed Brown 149520f4b53cSBarry Smith Logically Collective 1496e27a552bSJed Brown 1497d8d19677SJose E. Roman Input Parameters: 1498e27a552bSJed Brown + ts - timestepping context 1499bcf0153eSBarry Smith - flg - `PETSC_TRUE` to recompute the Jacobian at each stage 1500e27a552bSJed Brown 1501e27a552bSJed Brown Level: intermediate 1502e27a552bSJed Brown 15031cc06b55SBarry Smith .seealso: [](ch_ts), `TSRosWType`, `TSRosWGetType()` 1504e27a552bSJed Brown @*/ 1505d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRosWSetRecomputeJacobian(TS ts, PetscBool flg) 1506d71ae5a4SJacob Faibussowitsch { 1507e27a552bSJed Brown PetscFunctionBegin; 1508e27a552bSJed Brown PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 1509cac4c232SBarry Smith PetscTryMethod(ts, "TSRosWSetRecomputeJacobian_C", (TS, PetscBool), (ts, flg)); 15103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1511e27a552bSJed Brown } 1512e27a552bSJed Brown 1513d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSRosWGetType_RosW(TS ts, TSRosWType *rostype) 1514d71ae5a4SJacob Faibussowitsch { 151561692a83SJed Brown TS_RosW *ros = (TS_RosW *)ts->data; 1516e27a552bSJed Brown 1517e27a552bSJed Brown PetscFunctionBegin; 151861692a83SJed Brown *rostype = ros->tableau->name; 15193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1520e27a552bSJed Brown } 1521ef20d060SBarry Smith 1522d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSRosWSetType_RosW(TS ts, TSRosWType rostype) 1523d71ae5a4SJacob Faibussowitsch { 152461692a83SJed Brown TS_RosW *ros = (TS_RosW *)ts->data; 1525e27a552bSJed Brown PetscBool match; 152661692a83SJed Brown RosWTableauLink link; 1527e27a552bSJed Brown 1528e27a552bSJed Brown PetscFunctionBegin; 152961692a83SJed Brown if (ros->tableau) { 15309566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(ros->tableau->name, rostype, &match)); 15313ba16761SJacob Faibussowitsch if (match) PetscFunctionReturn(PETSC_SUCCESS); 1532e27a552bSJed Brown } 153361692a83SJed Brown for (link = RosWTableauList; link; link = link->next) { 15349566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(link->tab.name, rostype, &match)); 1535e27a552bSJed Brown if (match) { 15369566063dSJacob Faibussowitsch if (ts->setupcalled) PetscCall(TSRosWTableauReset(ts)); 153761692a83SJed Brown ros->tableau = &link->tab; 15389566063dSJacob Faibussowitsch if (ts->setupcalled) PetscCall(TSRosWTableauSetUp(ts)); 15392ffb9264SLisandro Dalcin ts->default_adapt_type = ros->tableau->bembed ? TSADAPTBASIC : TSADAPTNONE; 15403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1541e27a552bSJed Brown } 1542e27a552bSJed Brown } 154398921bdaSJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_UNKNOWN_TYPE, "Could not find '%s'", rostype); 1544e27a552bSJed Brown } 154561692a83SJed Brown 1546d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSRosWSetRecomputeJacobian_RosW(TS ts, PetscBool flg) 1547d71ae5a4SJacob Faibussowitsch { 154861692a83SJed Brown TS_RosW *ros = (TS_RosW *)ts->data; 1549e27a552bSJed Brown 1550e27a552bSJed Brown PetscFunctionBegin; 155161692a83SJed Brown ros->recompute_jacobian = flg; 15523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1553e27a552bSJed Brown } 1554e27a552bSJed Brown 1555d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSDestroy_RosW(TS ts) 1556d71ae5a4SJacob Faibussowitsch { 1557b3a6b972SJed Brown PetscFunctionBegin; 15589566063dSJacob Faibussowitsch PetscCall(TSReset_RosW(ts)); 1559b3a6b972SJed Brown if (ts->dm) { 15609566063dSJacob Faibussowitsch PetscCall(DMCoarsenHookRemove(ts->dm, DMCoarsenHook_TSRosW, DMRestrictHook_TSRosW, ts)); 15619566063dSJacob Faibussowitsch PetscCall(DMSubDomainHookRemove(ts->dm, DMSubDomainHook_TSRosW, DMSubDomainRestrictHook_TSRosW, ts)); 1562b3a6b972SJed Brown } 15639566063dSJacob Faibussowitsch PetscCall(PetscFree(ts->data)); 15649566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSRosWGetType_C", NULL)); 15659566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSRosWSetType_C", NULL)); 15669566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSRosWSetRecomputeJacobian_C", NULL)); 15673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1568b3a6b972SJed Brown } 1569d5e6173cSPeter Brune 1570e27a552bSJed Brown /* ------------------------------------------------------------ */ 1571e27a552bSJed Brown /*MC 1572020d8f30SJed Brown TSROSW - ODE solver using Rosenbrock-W schemes 1573e27a552bSJed Brown 1574e27a552bSJed Brown These methods are intended for problems with well-separated time scales, especially when a slow scale is strongly 1575e27a552bSJed Brown nonlinear such that it is expensive to solve with a fully implicit method. The user should provide the stiff part 1576bcf0153eSBarry Smith of the equation using `TSSetIFunction()` and the non-stiff part with `TSSetRHSFunction()`. 1577bcf0153eSBarry Smith 1578bcf0153eSBarry Smith Level: beginner 1579e27a552bSJed Brown 1580e27a552bSJed Brown Notes: 158161692a83SJed Brown This method currently only works with autonomous ODE and DAE. 158261692a83SJed Brown 1583bcf0153eSBarry Smith Consider trying `TSARKIMEX` if the stiff part is strongly nonlinear. 1584d0685a90SJed Brown 15853d5a8a6aSBarry 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 15863d5a8a6aSBarry Smith 1587e94cfbe0SPatrick Sanan Developer Notes: 158861692a83SJed Brown Rosenbrock-W methods are typically specified for autonomous ODE 158961692a83SJed Brown 1590f9c1d6abSBarry Smith $ udot = f(u) 159161692a83SJed Brown 159261692a83SJed Brown by the stage equations 159361692a83SJed Brown 1594f9c1d6abSBarry Smith $ k_i = h f(u_0 + sum_j alpha_ij k_j) + h J sum_j gamma_ij k_j 159561692a83SJed Brown 159661692a83SJed Brown and step completion formula 159761692a83SJed Brown 1598f9c1d6abSBarry Smith $ u_1 = u_0 + sum_j b_j k_j 159961692a83SJed Brown 1600f9c1d6abSBarry Smith with step size h and coefficients alpha_ij, gamma_ij, and b_i. Implementing the method in this form would require f(u) 160161692a83SJed Brown and the Jacobian J to be available, in addition to the shifted matrix I - h gamma_ii J. Following Hairer and Wanner, 160261692a83SJed Brown we define new variables for the stage equations 160361692a83SJed Brown 160461692a83SJed Brown $ y_i = gamma_ij k_j 160561692a83SJed Brown 160661692a83SJed Brown The k_j can be recovered because Gamma is invertible. Let C be the lower triangular part of Gamma^{-1} and define 160761692a83SJed Brown 1608b70472e2SJed Brown $ A = Alpha Gamma^{-1}, bt^T = b^T Gamma^{-1} 160961692a83SJed Brown 161061692a83SJed Brown to rewrite the method as 161161692a83SJed Brown 161237fdd005SBarry Smith .vb 161337fdd005SBarry 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 161437fdd005SBarry Smith u_1 = u_0 + sum_j bt_j y_j 161537fdd005SBarry Smith .ve 161661692a83SJed Brown 161761692a83SJed Brown where we have introduced the mass matrix M. Continue by defining 161861692a83SJed Brown 161961692a83SJed Brown $ ydot_i = 1/(h gamma_ii) y_i - sum_j (c_ij/h) y_j 162061692a83SJed Brown 162161692a83SJed Brown or, more compactly in tensor notation 162261692a83SJed Brown 162361692a83SJed Brown $ Ydot = 1/h (Gamma^{-1} \otimes I) Y . 162461692a83SJed Brown 162561692a83SJed Brown Note that Gamma^{-1} is lower triangular. With this definition of Ydot in terms of known quantities and the current 162661692a83SJed Brown stage y_i, the stage equations reduce to performing one Newton step (typically with a lagged Jacobian) on the 162761692a83SJed Brown equation 162861692a83SJed Brown 1629f9c1d6abSBarry Smith $ g(u_0 + sum_j a_ij y_j + y_i, ydot_i) = 0 163061692a83SJed Brown 163161692a83SJed Brown with initial guess y_i = 0. 1632e27a552bSJed Brown 16331cc06b55SBarry Smith .seealso: [](ch_ts), `TSCreate()`, `TS`, `TSSetType()`, `TSRosWSetType()`, `TSRosWRegister()`, `TSROSWTHETA1`, `TSROSWTHETA2`, `TSROSW2M`, `TSROSW2P`, `TSROSWRA3PW`, `TSROSWRA34PW2`, `TSROSWRODAS3`, 1634bcf0153eSBarry Smith `TSROSWSANDU3`, `TSROSWASSP3P3S1C`, `TSROSWLASSP3P4S2C`, `TSROSWLLSSP3P4S2C`, `TSROSWGRK4T`, `TSROSWSHAMP4`, `TSROSWVELDD4`, `TSROSW4L`, `TSType` 1635e27a552bSJed Brown M*/ 1636d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode TSCreate_RosW(TS ts) 1637d71ae5a4SJacob Faibussowitsch { 163861692a83SJed Brown TS_RosW *ros; 1639e27a552bSJed Brown 1640e27a552bSJed Brown PetscFunctionBegin; 16419566063dSJacob Faibussowitsch PetscCall(TSRosWInitializePackage()); 1642e27a552bSJed Brown 1643e27a552bSJed Brown ts->ops->reset = TSReset_RosW; 1644e27a552bSJed Brown ts->ops->destroy = TSDestroy_RosW; 1645e27a552bSJed Brown ts->ops->view = TSView_RosW; 16469200755eSBarry Smith ts->ops->load = TSLoad_RosW; 1647e27a552bSJed Brown ts->ops->setup = TSSetUp_RosW; 1648e27a552bSJed Brown ts->ops->step = TSStep_RosW; 1649e27a552bSJed Brown ts->ops->interpolate = TSInterpolate_RosW; 16501c3436cfSJed Brown ts->ops->evaluatestep = TSEvaluateStep_RosW; 1651e27a552bSJed Brown ts->ops->setfromoptions = TSSetFromOptions_RosW; 1652e27a552bSJed Brown ts->ops->snesfunction = SNESTSFormFunction_RosW; 1653e27a552bSJed Brown ts->ops->snesjacobian = SNESTSFormJacobian_RosW; 1654e27a552bSJed Brown 1655efd4aadfSBarry Smith ts->usessnes = PETSC_TRUE; 1656efd4aadfSBarry Smith 16574dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&ros)); 165861692a83SJed Brown ts->data = (void *)ros; 1659e27a552bSJed Brown 16609566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSRosWGetType_C", TSRosWGetType_RosW)); 16619566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSRosWSetType_C", TSRosWSetType_RosW)); 16629566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSRosWSetRecomputeJacobian_C", TSRosWSetRecomputeJacobian_RosW)); 1663b39943a6SLisandro Dalcin 16649566063dSJacob Faibussowitsch PetscCall(TSRosWSetType(ts, TSRosWDefault)); 16653ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1666e27a552bSJed Brown } 1667