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 761692a83SJed Brown G(t,X,Xdot) = F(t,X) 8e27a552bSJed Brown 961692a83SJed Brown where G represents the stiff part of the physics and F represents the non-stiff part. 1061692a83SJed Brown This method is designed to be linearly implicit on G and can use an approximate and lagged Jacobian. 11e27a552bSJed Brown 12e27a552bSJed Brown */ 13e27a552bSJed Brown #include <private/tsimpl.h> /*I "petscts.h" I*/ 14e27a552bSJed Brown 1561692a83SJed Brown #include <../src/mat/blockinvert.h> 1661692a83SJed Brown 17ae6f9490SJed Brown static const TSRosWType TSRosWDefault = TSROSWRA34PW2; 18e27a552bSJed Brown static PetscBool TSRosWRegisterAllCalled; 19e27a552bSJed Brown static PetscBool TSRosWPackageInitialized; 20e27a552bSJed Brown 2161692a83SJed Brown typedef struct _RosWTableau *RosWTableau; 2261692a83SJed Brown struct _RosWTableau { 23e27a552bSJed Brown char *name; 24e27a552bSJed Brown PetscInt order; /* Classical approximation order of the method */ 25e27a552bSJed Brown PetscInt s; /* Number of stages */ 2661692a83SJed Brown PetscReal *A; /* Propagation table, strictly lower triangular */ 2761692a83SJed Brown PetscReal *Gamma; /* Stage table, lower triangular with nonzero diagonal */ 28c17803e7SJed Brown PetscBool *GammaZeroDiag; /* Diagonal entries that are zero in stage table Gamma, vector indicating explicit statages */ 2943b21953SEmil Constantinescu PetscReal *GammaExplicitCorr; /* Coefficients for correction terms needed for explicit stages in transformed variables*/ 3061692a83SJed Brown PetscReal *b; /* Step completion table */ 31fe7e6d57SJed Brown PetscReal *bembed; /* Step completion table for embedded method of order one less */ 3261692a83SJed Brown PetscReal *ASum; /* Row sum of A */ 3361692a83SJed Brown PetscReal *GammaSum; /* Row sum of Gamma, only needed for non-autonomous systems */ 3461692a83SJed Brown PetscReal *At; /* Propagation table in transformed variables */ 3561692a83SJed Brown PetscReal *bt; /* Step completion table in transformed variables */ 36fe7e6d57SJed Brown PetscReal *bembedt; /* Step completion table of order one less in transformed variables */ 3761692a83SJed Brown PetscReal *GammaInv; /* Inverse of Gamma, used for transformed variables */ 388d59e960SJed Brown PetscReal ccfl; /* Placeholder for CFL coefficient relative to forward Euler */ 39e27a552bSJed Brown }; 4061692a83SJed Brown typedef struct _RosWTableauLink *RosWTableauLink; 4161692a83SJed Brown struct _RosWTableauLink { 4261692a83SJed Brown struct _RosWTableau tab; 4361692a83SJed Brown RosWTableauLink next; 44e27a552bSJed Brown }; 4561692a83SJed Brown static RosWTableauLink RosWTableauList; 46e27a552bSJed Brown 47e27a552bSJed Brown typedef struct { 4861692a83SJed Brown RosWTableau tableau; 4961692a83SJed Brown Vec *Y; /* States computed during the step, used to complete the step */ 50e27a552bSJed Brown Vec Ydot; /* Work vector holding Ydot during residual evaluation */ 5161692a83SJed Brown Vec Ystage; /* Work vector for the state value at each stage */ 5261692a83SJed Brown Vec Zdot; /* Ydot = Zdot + shift*Y */ 5361692a83SJed Brown Vec Zstage; /* Y = Zstage + Y */ 541c3436cfSJed Brown PetscScalar *work; /* Scalar work space of length number of stages, used to prepare VecMAXPY() */ 55e27a552bSJed Brown PetscReal shift; 56e27a552bSJed Brown PetscReal stage_time; 57c17803e7SJed Brown PetscReal stage_explicit; /* Flag indicates that the current stage is explicit */ 5861692a83SJed Brown PetscBool recompute_jacobian; /* Recompute the Jacobian at each stage, default is to freeze the Jacobian at the start of each step */ 59108c343cSJed Brown TSStepStatus status; 60e27a552bSJed Brown } TS_RosW; 61e27a552bSJed Brown 62fe7e6d57SJed Brown /*MC 633606a31eSEmil Constantinescu TSROSWTHETA1 - One stage first order L-stable Rosenbrock-W scheme (aka theta method). 643606a31eSEmil Constantinescu 653606a31eSEmil Constantinescu Only an approximate Jacobian is needed. 663606a31eSEmil Constantinescu 673606a31eSEmil Constantinescu Level: intermediate 683606a31eSEmil Constantinescu 693606a31eSEmil Constantinescu .seealso: TSROSW 703606a31eSEmil Constantinescu M*/ 713606a31eSEmil Constantinescu 723606a31eSEmil Constantinescu /*MC 733606a31eSEmil Constantinescu TSROSWTHETA2 - One stage second order A-stable Rosenbrock-W scheme (aka theta method). 743606a31eSEmil Constantinescu 753606a31eSEmil Constantinescu Only an approximate Jacobian is needed. 763606a31eSEmil Constantinescu 773606a31eSEmil Constantinescu Level: intermediate 783606a31eSEmil Constantinescu 793606a31eSEmil Constantinescu .seealso: TSROSW 803606a31eSEmil Constantinescu M*/ 813606a31eSEmil Constantinescu 823606a31eSEmil Constantinescu /*MC 83fe7e6d57SJed Brown TSROSW2M - Two stage second order L-stable Rosenbrock-W scheme. 84fe7e6d57SJed Brown 85fe7e6d57SJed Brown Only an approximate Jacobian is needed. By default, it is only recomputed once per step. This method is a reflection of TSROSW2P. 86fe7e6d57SJed Brown 87fe7e6d57SJed Brown Level: intermediate 88fe7e6d57SJed Brown 89fe7e6d57SJed Brown .seealso: TSROSW 90fe7e6d57SJed Brown M*/ 91fe7e6d57SJed Brown 92fe7e6d57SJed Brown /*MC 93fe7e6d57SJed Brown TSROSW2P - Two stage second order L-stable Rosenbrock-W scheme. 94fe7e6d57SJed Brown 95fe7e6d57SJed Brown Only an approximate Jacobian is needed. By default, it is only recomputed once per step. This method is a reflection of TSROSW2M. 96fe7e6d57SJed Brown 97fe7e6d57SJed Brown Level: intermediate 98fe7e6d57SJed Brown 99fe7e6d57SJed Brown .seealso: TSROSW 100fe7e6d57SJed Brown M*/ 101fe7e6d57SJed Brown 102fe7e6d57SJed Brown /*MC 103fe7e6d57SJed Brown TSROSWRA3PW - Three stage third order Rosenbrock-W scheme for PDAE of index 1. 104fe7e6d57SJed Brown 105fe7e6d57SJed Brown Only an approximate Jacobian is needed. By default, it is only recomputed once per step. 106fe7e6d57SJed Brown 107fe7e6d57SJed 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. 108fe7e6d57SJed Brown 109fe7e6d57SJed Brown References: 110fe7e6d57SJed Brown Rang and Angermann, New Rosenbrock-W methods of order 3 for partial differential algebraic equations of index 1, 2005. 111fe7e6d57SJed Brown 112fe7e6d57SJed Brown Level: intermediate 113fe7e6d57SJed Brown 114fe7e6d57SJed Brown .seealso: TSROSW 115fe7e6d57SJed Brown M*/ 116fe7e6d57SJed Brown 117fe7e6d57SJed Brown /*MC 118fe7e6d57SJed Brown TSROSWRA34PW2 - Four stage third order L-stable Rosenbrock-W scheme for PDAE of index 1. 119fe7e6d57SJed Brown 120fe7e6d57SJed Brown Only an approximate Jacobian is needed. By default, it is only recomputed once per step. 121fe7e6d57SJed Brown 122fe7e6d57SJed 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. 123fe7e6d57SJed Brown 124fe7e6d57SJed Brown References: 125fe7e6d57SJed Brown Rang and Angermann, New Rosenbrock-W methods of order 3 for partial differential algebraic equations of index 1, 2005. 126fe7e6d57SJed Brown 127fe7e6d57SJed Brown Level: intermediate 128fe7e6d57SJed Brown 129fe7e6d57SJed Brown .seealso: TSROSW 130fe7e6d57SJed Brown M*/ 131fe7e6d57SJed Brown 132ef3c5b88SJed Brown /*MC 133ef3c5b88SJed Brown TSROSWRODAS3 - Four stage third order L-stable Rosenbrock scheme 134ef3c5b88SJed Brown 135ef3c5b88SJed Brown By default, the Jacobian is only recomputed once per step. 136ef3c5b88SJed Brown 137ef3c5b88SJed Brown Both the third order and embedded second order methods are stiffly accurate and L-stable. 138ef3c5b88SJed Brown 139ef3c5b88SJed Brown References: 140ef3c5b88SJed Brown Sandu et al, Benchmarking stiff ODE solvers for atmospheric chemistry problems II, Rosenbrock solvers, 1997. 141ef3c5b88SJed Brown 142ef3c5b88SJed Brown Level: intermediate 143ef3c5b88SJed Brown 144ef3c5b88SJed Brown .seealso: TSROSW, TSROSWSANDU3 145ef3c5b88SJed Brown M*/ 146ef3c5b88SJed Brown 147ef3c5b88SJed Brown /*MC 148ef3c5b88SJed Brown TSROSWSANDU3 - Three stage third order L-stable Rosenbrock scheme 149ef3c5b88SJed Brown 150ef3c5b88SJed Brown By default, the Jacobian is only recomputed once per step. 151ef3c5b88SJed Brown 152ef3c5b88SJed Brown The third order method is L-stable, but not stiffly accurate. 153ef3c5b88SJed Brown The second order embedded method is strongly A-stable with R(infty) = 0.5. 154ef3c5b88SJed Brown The internal stages are L-stable. 155ef3c5b88SJed Brown This method is called ROS3 in the paper. 156ef3c5b88SJed Brown 157ef3c5b88SJed Brown References: 158ef3c5b88SJed Brown Sandu et al, Benchmarking stiff ODE solvers for atmospheric chemistry problems II, Rosenbrock solvers, 1997. 159ef3c5b88SJed Brown 160ef3c5b88SJed Brown Level: intermediate 161ef3c5b88SJed Brown 162ef3c5b88SJed Brown .seealso: TSROSW, TSROSWRODAS3 163ef3c5b88SJed Brown M*/ 164ef3c5b88SJed Brown 165961f28d0SJed Brown /*MC 166961f28d0SJed Brown TSROSWASSP3P3S1C - A-stable Rosenbrock-W method with SSP explicit part, third order, three stages 167961f28d0SJed Brown 168961f28d0SJed Brown By default, the Jacobian is only recomputed once per step. 169961f28d0SJed Brown 170961f28d0SJed Brown A-stable SPP explicit order 3, 3 stages, CFL 1 (eff = 1/3) 171961f28d0SJed Brown 172961f28d0SJed Brown References: 173961f28d0SJed Brown Emil Constantinescu 174961f28d0SJed Brown 175961f28d0SJed Brown Level: intermediate 176961f28d0SJed Brown 17743b21953SEmil Constantinescu .seealso: TSROSW, TSROSWLASSP3P4S2C, TSROSWLLSSP3P4S2C, SSP 178961f28d0SJed Brown M*/ 179961f28d0SJed Brown 180961f28d0SJed Brown /*MC 181961f28d0SJed Brown TSROSWLASSP3P4S2C - L-stable Rosenbrock-W method with SSP explicit part, third order, three stages 182961f28d0SJed Brown 183961f28d0SJed Brown By default, the Jacobian is only recomputed once per step. 184961f28d0SJed Brown 185961f28d0SJed Brown L-stable (A-stable embedded) SPP explicit order 3, 4 stages, CFL 2 (eff = 1/2) 186961f28d0SJed Brown 187961f28d0SJed Brown References: 188961f28d0SJed Brown Emil Constantinescu 189961f28d0SJed Brown 190961f28d0SJed Brown Level: intermediate 191961f28d0SJed Brown 19243b21953SEmil Constantinescu .seealso: TSROSW, TSROSWASSP3P3S1C, TSROSWLLSSP3P4S2C, TSSSP 193961f28d0SJed Brown M*/ 194961f28d0SJed Brown 195961f28d0SJed Brown /*MC 19643b21953SEmil Constantinescu TSROSWLLSSP3P4S2C - L-stable Rosenbrock-W method with SSP explicit part, third order, three stages 197961f28d0SJed Brown 198961f28d0SJed Brown By default, the Jacobian is only recomputed once per step. 199961f28d0SJed Brown 200961f28d0SJed Brown L-stable (L-stable embedded) SPP explicit order 3, 4 stages, CFL 2 (eff = 1/2) 201961f28d0SJed Brown 202961f28d0SJed Brown References: 203961f28d0SJed Brown Emil Constantinescu 204961f28d0SJed Brown 205961f28d0SJed Brown Level: intermediate 206961f28d0SJed Brown 207961f28d0SJed Brown .seealso: TSROSW, TSROSWASSP3P3S1C, TSROSWLASSP3P4S2C, TSSSP 208961f28d0SJed Brown M*/ 209961f28d0SJed Brown 210e27a552bSJed Brown #undef __FUNCT__ 211e27a552bSJed Brown #define __FUNCT__ "TSRosWRegisterAll" 212e27a552bSJed Brown /*@C 213e27a552bSJed Brown TSRosWRegisterAll - Registers all of the additive Runge-Kutta implicit-explicit methods in TSRosW 214e27a552bSJed Brown 215e27a552bSJed Brown Not Collective, but should be called by all processes which will need the schemes to be registered 216e27a552bSJed Brown 217e27a552bSJed Brown Level: advanced 218e27a552bSJed Brown 219e27a552bSJed Brown .keywords: TS, TSRosW, register, all 220e27a552bSJed Brown 221e27a552bSJed Brown .seealso: TSRosWRegisterDestroy() 222e27a552bSJed Brown @*/ 223e27a552bSJed Brown PetscErrorCode TSRosWRegisterAll(void) 224e27a552bSJed Brown { 225e27a552bSJed Brown PetscErrorCode ierr; 226e27a552bSJed Brown 227e27a552bSJed Brown PetscFunctionBegin; 228e27a552bSJed Brown if (TSRosWRegisterAllCalled) PetscFunctionReturn(0); 229e27a552bSJed Brown TSRosWRegisterAllCalled = PETSC_TRUE; 230e27a552bSJed Brown 231e27a552bSJed Brown { 2323606a31eSEmil Constantinescu const PetscReal 2333606a31eSEmil Constantinescu A = 0, 2343606a31eSEmil Constantinescu Gamma = 1, 2353606a31eSEmil Constantinescu b = 1; 2363606a31eSEmil Constantinescu ierr = TSRosWRegister(TSROSWTHETA1,1,1,&A,&Gamma,&b,PETSC_NULL);CHKERRQ(ierr); 2373606a31eSEmil Constantinescu } 2383606a31eSEmil Constantinescu 2393606a31eSEmil Constantinescu { 2403606a31eSEmil Constantinescu const PetscReal 2413606a31eSEmil Constantinescu A= 0, 2423606a31eSEmil Constantinescu Gamma = 0.5, 2433606a31eSEmil Constantinescu b = 1; 2443606a31eSEmil Constantinescu ierr = TSRosWRegister(TSROSWTHETA2,2,1,&A,&Gamma,&b,PETSC_NULL);CHKERRQ(ierr); 2453606a31eSEmil Constantinescu } 2463606a31eSEmil Constantinescu 2473606a31eSEmil Constantinescu { 24861692a83SJed Brown const PetscReal g = 1. + 1./PetscSqrtReal(2.0); 249e27a552bSJed Brown const PetscReal 25061692a83SJed Brown A[2][2] = {{0,0}, {1.,0}}, 25161692a83SJed Brown Gamma[2][2] = {{g,0}, {-2.*g,g}}, 2521c3436cfSJed Brown b[2] = {0.5,0.5}, 2531c3436cfSJed Brown b1[2] = {1.0,0.0}; 2541c3436cfSJed Brown ierr = TSRosWRegister(TSROSW2P,2,2,&A[0][0],&Gamma[0][0],b,b1);CHKERRQ(ierr); 255e27a552bSJed Brown } 256e27a552bSJed Brown { 25761692a83SJed Brown const PetscReal g = 1. - 1./PetscSqrtReal(2.0); 258e27a552bSJed Brown const PetscReal 25961692a83SJed Brown A[2][2] = {{0,0}, {1.,0}}, 26061692a83SJed Brown Gamma[2][2] = {{g,0}, {-2.*g,g}}, 2611c3436cfSJed Brown b[2] = {0.5,0.5}, 2621c3436cfSJed Brown b1[2] = {1.0,0.0}; 2631c3436cfSJed Brown ierr = TSRosWRegister(TSROSW2M,2,2,&A[0][0],&Gamma[0][0],b,b1);CHKERRQ(ierr); 264fe7e6d57SJed Brown } 265fe7e6d57SJed Brown { 266fe7e6d57SJed Brown const PetscReal g = 7.8867513459481287e-01; 267fe7e6d57SJed Brown const PetscReal 268fe7e6d57SJed Brown A[3][3] = {{0,0,0}, 269fe7e6d57SJed Brown {1.5773502691896257e+00,0,0}, 270fe7e6d57SJed Brown {0.5,0,0}}, 271fe7e6d57SJed Brown Gamma[3][3] = {{g,0,0}, 272fe7e6d57SJed Brown {-1.5773502691896257e+00,g,0}, 273fe7e6d57SJed Brown {-6.7075317547305480e-01,1.7075317547305482e-01,g}}, 274fe7e6d57SJed Brown b[3] = {1.0566243270259355e-01,4.9038105676657971e-02,8.4529946162074843e-01}, 275fe7e6d57SJed Brown b2[3] = {-1.7863279495408180e-01,1./3.,8.4529946162074843e-01}; 276fe7e6d57SJed Brown ierr = TSRosWRegister(TSROSWRA3PW,3,3,&A[0][0],&Gamma[0][0],b,b2);CHKERRQ(ierr); 277fe7e6d57SJed Brown } 278fe7e6d57SJed Brown { 279fe7e6d57SJed Brown const PetscReal g = 4.3586652150845900e-01; 280fe7e6d57SJed Brown const PetscReal 281fe7e6d57SJed Brown A[4][4] = {{0,0,0,0}, 282fe7e6d57SJed Brown {8.7173304301691801e-01,0,0,0}, 283fe7e6d57SJed Brown {8.4457060015369423e-01,-1.1299064236484185e-01,0,0}, 284fe7e6d57SJed Brown {0,0,1.,0}}, 285fe7e6d57SJed Brown Gamma[4][4] = {{g,0,0,0}, 286fe7e6d57SJed Brown {-8.7173304301691801e-01,g,0,0}, 287fe7e6d57SJed Brown {-9.0338057013044082e-01,5.4180672388095326e-02,g,0}, 288fe7e6d57SJed Brown {2.4212380706095346e-01,-1.2232505839045147e+00,5.4526025533510214e-01,g}}, 289fe7e6d57SJed Brown b[4] = {2.4212380706095346e-01,-1.2232505839045147e+00,1.5452602553351020e+00,4.3586652150845900e-01}, 290fe7e6d57SJed Brown b2[4] = {3.7810903145819369e-01,-9.6042292212423178e-02,5.0000000000000000e-01,2.1793326075422950e-01}; 291fe7e6d57SJed Brown ierr = TSRosWRegister(TSROSWRA34PW2,3,4,&A[0][0],&Gamma[0][0],b,b2);CHKERRQ(ierr); 292e27a552bSJed Brown } 293ef3c5b88SJed Brown { 294ef3c5b88SJed Brown const PetscReal g = 0.5; 295ef3c5b88SJed Brown const PetscReal 296ef3c5b88SJed Brown A[4][4] = {{0,0,0,0}, 297ef3c5b88SJed Brown {0,0,0,0}, 298ef3c5b88SJed Brown {1.,0,0,0}, 299ef3c5b88SJed Brown {0.75,-0.25,0.5,0}}, 300ef3c5b88SJed Brown Gamma[4][4] = {{g,0,0,0}, 301ef3c5b88SJed Brown {1.,g,0,0}, 302ef3c5b88SJed Brown {-0.25,-0.25,g,0}, 303ef3c5b88SJed Brown {1./12,1./12,-2./3,g}}, 304ef3c5b88SJed Brown b[4] = {5./6,-1./6,-1./6,0.5}, 305ef3c5b88SJed Brown b2[4] = {0.75,-0.25,0.5,0}; 306ef3c5b88SJed Brown ierr = TSRosWRegister(TSROSWRODAS3,3,4,&A[0][0],&Gamma[0][0],b,b2);CHKERRQ(ierr); 307ef3c5b88SJed Brown } 308ef3c5b88SJed Brown { 309ef3c5b88SJed Brown const PetscReal g = 0.43586652150845899941601945119356; 310ef3c5b88SJed Brown const PetscReal 311ef3c5b88SJed Brown A[3][3] = {{0,0,0}, 312ef3c5b88SJed Brown {g,0,0}, 313ef3c5b88SJed Brown {g,0,0}}, 314ef3c5b88SJed Brown Gamma[3][3] = {{g,0,0}, 315ef3c5b88SJed Brown {-0.19294655696029095575009695436041,g,0}, 316ef3c5b88SJed Brown {0,1.74927148125794685173529749738960,g}}, 317ef3c5b88SJed Brown b[3] = {-0.75457412385404315829818998646589,1.94100407061964420292840123379419,-0.18642994676560104463021124732829}, 318ef3c5b88SJed Brown b2[3] = {-1.53358745784149585370766523913002,2.81745131148625772213931745457622,-0.28386385364476186843165221544619}; 319ef3c5b88SJed Brown ierr = TSRosWRegister(TSROSWSANDU3,3,3,&A[0][0],&Gamma[0][0],b,b2);CHKERRQ(ierr); 320ef3c5b88SJed Brown } 321b1c69cc3SEmil Constantinescu { 322*aaf9cf16SJed Brown const PetscReal s3 = PetscSqrtReal(3.),g = (3.0+s3)/6.0; 323b1c69cc3SEmil Constantinescu const PetscReal 324b1c69cc3SEmil Constantinescu A[3][3] = {{0,0,0}, 325b1c69cc3SEmil Constantinescu {1,0,0}, 326b1c69cc3SEmil Constantinescu {0.25,0.25,0}}, 327b1c69cc3SEmil Constantinescu Gamma[3][3] = {{0,0,0}, 328*aaf9cf16SJed Brown {(-3.0-s3)/6.0,g,0}, 329*aaf9cf16SJed Brown {(-3.0-s3)/24.0,(-3.0-s3)/8.0,g}}, 330b1c69cc3SEmil Constantinescu b[3] = {1./6.,1./6.,2./3.}, 331b1c69cc3SEmil Constantinescu b2[3] = {1./4.,1./4.,1./2.}; 332b1c69cc3SEmil Constantinescu ierr = TSRosWRegister(TSROSWASSP3P3S1C,3,3,&A[0][0],&Gamma[0][0],b,b2);CHKERRQ(ierr); 333b1c69cc3SEmil Constantinescu } 334b1c69cc3SEmil Constantinescu 335b1c69cc3SEmil Constantinescu { 336b1c69cc3SEmil Constantinescu const PetscReal 337b1c69cc3SEmil Constantinescu A[4][4] = {{0,0,0,0}, 338b1c69cc3SEmil Constantinescu {1./2.,0,0,0}, 339b1c69cc3SEmil Constantinescu {1./2.,1./2.,0,0}, 340b1c69cc3SEmil Constantinescu {1./6.,1./6.,1./6.,0}}, 341b1c69cc3SEmil Constantinescu Gamma[4][4] = {{1./2.,0,0,0}, 342b1c69cc3SEmil Constantinescu {0.0,1./4.,0,0}, 343b1c69cc3SEmil Constantinescu {-2.,-2./3.,2./3.,0}, 344b1c69cc3SEmil Constantinescu {1./2.,5./36.,-2./9,0}}, 345b1c69cc3SEmil Constantinescu b[4] = {1./6.,1./6.,1./6.,1./2.}, 346b1c69cc3SEmil Constantinescu b2[4] = {1./8.,3./4.,1./8.,0}; 347b1c69cc3SEmil Constantinescu ierr = TSRosWRegister(TSROSWLASSP3P4S2C,3,4,&A[0][0],&Gamma[0][0],b,b2);CHKERRQ(ierr); 348b1c69cc3SEmil Constantinescu } 349b1c69cc3SEmil Constantinescu 350b1c69cc3SEmil Constantinescu { 351b1c69cc3SEmil Constantinescu const PetscReal 352b1c69cc3SEmil Constantinescu A[4][4] = {{0,0,0,0}, 353b1c69cc3SEmil Constantinescu {1./2.,0,0,0}, 354b1c69cc3SEmil Constantinescu {1./2.,1./2.,0,0}, 355b1c69cc3SEmil Constantinescu {1./6.,1./6.,1./6.,0}}, 356b1c69cc3SEmil Constantinescu Gamma[4][4] = {{1./2.,0,0,0}, 357b1c69cc3SEmil Constantinescu {0.0,3./4.,0,0}, 358b1c69cc3SEmil Constantinescu {-2./3.,-23./9.,2./9.,0}, 359b1c69cc3SEmil Constantinescu {1./18.,65./108.,-2./27,0}}, 360b1c69cc3SEmil Constantinescu b[4] = {1./6.,1./6.,1./6.,1./2.}, 361b1c69cc3SEmil Constantinescu b2[4] = {3./16.,10./16.,3./16.,0}; 36243b21953SEmil Constantinescu ierr = TSRosWRegister(TSROSWLLSSP3P4S2C,3,4,&A[0][0],&Gamma[0][0],b,b2);CHKERRQ(ierr); 363b1c69cc3SEmil Constantinescu } 364753f8adbSEmil Constantinescu 365753f8adbSEmil Constantinescu { 366753f8adbSEmil Constantinescu PetscReal A[4][4],Gamma[4][4],b[4],b2[4]; 367753f8adbSEmil Constantinescu 368753f8adbSEmil Constantinescu Gamma[0][0]=0.4358665215084589994160194475295062513822671686978816; 36905e8e825SJed Brown Gamma[0][1]=0; Gamma[0][2]=0; Gamma[0][3]=0; 370753f8adbSEmil Constantinescu Gamma[1][0]=-1.997527830934941248426324674704153457289527280554476; 371753f8adbSEmil Constantinescu Gamma[1][1]=0.4358665215084589994160194475295062513822671686978816; 37205e8e825SJed Brown Gamma[1][2]=0; Gamma[1][3]=0; 373753f8adbSEmil Constantinescu Gamma[2][0]=-1.007948511795029620852002345345404191008352770119903; 374753f8adbSEmil Constantinescu Gamma[2][1]=-0.004648958462629345562774289390054679806993396798458131; 375753f8adbSEmil Constantinescu Gamma[2][2]=0.4358665215084589994160194475295062513822671686978816; 37605e8e825SJed Brown Gamma[2][3]=0; 377753f8adbSEmil Constantinescu Gamma[3][0]=-0.6685429734233467180451604600279552604364311322650783; 378753f8adbSEmil Constantinescu Gamma[3][1]=0.6056625986449338476089525334450053439525178740492984; 379753f8adbSEmil Constantinescu Gamma[3][2]=-0.9717899277217721234705114616271378792182450260943198; 380753f8adbSEmil Constantinescu Gamma[3][3]=0; 381753f8adbSEmil Constantinescu 38205e8e825SJed Brown A[0][0]=0; A[0][1]=0; A[0][2]=0; A[0][3]=0; 383753f8adbSEmil Constantinescu A[1][0]=0.8717330430169179988320388950590125027645343373957631; 38405e8e825SJed Brown A[1][1]=0; A[1][2]=0; A[1][3]=0; 385753f8adbSEmil Constantinescu A[2][0]=0.5275890119763004115618079766722914408876108660811028; 386753f8adbSEmil Constantinescu A[2][1]=0.07241098802369958843819203208518599088698057726988732; 38705e8e825SJed Brown A[2][2]=0; A[2][3]=0; 388753f8adbSEmil Constantinescu A[3][0]=0.3990960076760701320627260685975778145384666450351314; 389753f8adbSEmil Constantinescu A[3][1]=-0.4375576546135194437228463747348862825846903771419953; 390753f8adbSEmil Constantinescu A[3][2]=1.038461646937449311660120300601880176655352737312713; 39105e8e825SJed Brown A[3][3]=0; 392753f8adbSEmil Constantinescu 393753f8adbSEmil Constantinescu b[0]=0.1876410243467238251612921333138006734899663569186926; 394753f8adbSEmil Constantinescu b[1]=-0.5952974735769549480478230473706443582188442040780541; 395753f8adbSEmil Constantinescu b[2]=0.9717899277217721234705114616271378792182450260943198; 396753f8adbSEmil Constantinescu b[3]=0.4358665215084589994160194475295062513822671686978816; 397753f8adbSEmil Constantinescu 398753f8adbSEmil Constantinescu b2[0]=0.2147402862233891404862383521089097657790734483804460; 399753f8adbSEmil Constantinescu b2[1]=-0.4851622638849390928209050538171743017757490232519684; 400753f8adbSEmil Constantinescu b2[2]=0.8687250025203875511662123688667549217531982787600080; 401753f8adbSEmil Constantinescu b2[3]=0.4016969751411624011684543450940068201770721128357014; 402753f8adbSEmil Constantinescu 403753f8adbSEmil Constantinescu ierr = TSRosWRegister(TSROSWARK3,3,4,&A[0][0],&Gamma[0][0],b,b2);CHKERRQ(ierr); 404753f8adbSEmil Constantinescu } 405753f8adbSEmil Constantinescu 406e27a552bSJed Brown PetscFunctionReturn(0); 407e27a552bSJed Brown } 408e27a552bSJed Brown 409e27a552bSJed Brown #undef __FUNCT__ 410e27a552bSJed Brown #define __FUNCT__ "TSRosWRegisterDestroy" 411e27a552bSJed Brown /*@C 412e27a552bSJed Brown TSRosWRegisterDestroy - Frees the list of schemes that were registered by TSRosWRegister(). 413e27a552bSJed Brown 414e27a552bSJed Brown Not Collective 415e27a552bSJed Brown 416e27a552bSJed Brown Level: advanced 417e27a552bSJed Brown 418e27a552bSJed Brown .keywords: TSRosW, register, destroy 419e27a552bSJed Brown .seealso: TSRosWRegister(), TSRosWRegisterAll(), TSRosWRegisterDynamic() 420e27a552bSJed Brown @*/ 421e27a552bSJed Brown PetscErrorCode TSRosWRegisterDestroy(void) 422e27a552bSJed Brown { 423e27a552bSJed Brown PetscErrorCode ierr; 42461692a83SJed Brown RosWTableauLink link; 425e27a552bSJed Brown 426e27a552bSJed Brown PetscFunctionBegin; 42761692a83SJed Brown while ((link = RosWTableauList)) { 42861692a83SJed Brown RosWTableau t = &link->tab; 42961692a83SJed Brown RosWTableauList = link->next; 43061692a83SJed Brown ierr = PetscFree5(t->A,t->Gamma,t->b,t->ASum,t->GammaSum);CHKERRQ(ierr); 43143b21953SEmil Constantinescu ierr = PetscFree5(t->At,t->bt,t->GammaInv,t->GammaZeroDiag,t->GammaExplicitCorr);CHKERRQ(ierr); 432fe7e6d57SJed Brown ierr = PetscFree2(t->bembed,t->bembedt);CHKERRQ(ierr); 433e27a552bSJed Brown ierr = PetscFree(t->name);CHKERRQ(ierr); 434e27a552bSJed Brown ierr = PetscFree(link);CHKERRQ(ierr); 435e27a552bSJed Brown } 436e27a552bSJed Brown TSRosWRegisterAllCalled = PETSC_FALSE; 437e27a552bSJed Brown PetscFunctionReturn(0); 438e27a552bSJed Brown } 439e27a552bSJed Brown 440e27a552bSJed Brown #undef __FUNCT__ 441e27a552bSJed Brown #define __FUNCT__ "TSRosWInitializePackage" 442e27a552bSJed Brown /*@C 443e27a552bSJed Brown TSRosWInitializePackage - This function initializes everything in the TSRosW package. It is called 444e27a552bSJed Brown from PetscDLLibraryRegister() when using dynamic libraries, and on the first call to TSCreate_RosW() 445e27a552bSJed Brown when using static libraries. 446e27a552bSJed Brown 447e27a552bSJed Brown Input Parameter: 448e27a552bSJed Brown path - The dynamic library path, or PETSC_NULL 449e27a552bSJed Brown 450e27a552bSJed Brown Level: developer 451e27a552bSJed Brown 452e27a552bSJed Brown .keywords: TS, TSRosW, initialize, package 453e27a552bSJed Brown .seealso: PetscInitialize() 454e27a552bSJed Brown @*/ 455e27a552bSJed Brown PetscErrorCode TSRosWInitializePackage(const char path[]) 456e27a552bSJed Brown { 457e27a552bSJed Brown PetscErrorCode ierr; 458e27a552bSJed Brown 459e27a552bSJed Brown PetscFunctionBegin; 460e27a552bSJed Brown if (TSRosWPackageInitialized) PetscFunctionReturn(0); 461e27a552bSJed Brown TSRosWPackageInitialized = PETSC_TRUE; 462e27a552bSJed Brown ierr = TSRosWRegisterAll();CHKERRQ(ierr); 463e27a552bSJed Brown ierr = PetscRegisterFinalize(TSRosWFinalizePackage);CHKERRQ(ierr); 464e27a552bSJed Brown PetscFunctionReturn(0); 465e27a552bSJed Brown } 466e27a552bSJed Brown 467e27a552bSJed Brown #undef __FUNCT__ 468e27a552bSJed Brown #define __FUNCT__ "TSRosWFinalizePackage" 469e27a552bSJed Brown /*@C 470e27a552bSJed Brown TSRosWFinalizePackage - This function destroys everything in the TSRosW package. It is 471e27a552bSJed Brown called from PetscFinalize(). 472e27a552bSJed Brown 473e27a552bSJed Brown Level: developer 474e27a552bSJed Brown 475e27a552bSJed Brown .keywords: Petsc, destroy, package 476e27a552bSJed Brown .seealso: PetscFinalize() 477e27a552bSJed Brown @*/ 478e27a552bSJed Brown PetscErrorCode TSRosWFinalizePackage(void) 479e27a552bSJed Brown { 480e27a552bSJed Brown PetscErrorCode ierr; 481e27a552bSJed Brown 482e27a552bSJed Brown PetscFunctionBegin; 483e27a552bSJed Brown TSRosWPackageInitialized = PETSC_FALSE; 484e27a552bSJed Brown ierr = TSRosWRegisterDestroy();CHKERRQ(ierr); 485e27a552bSJed Brown PetscFunctionReturn(0); 486e27a552bSJed Brown } 487e27a552bSJed Brown 488e27a552bSJed Brown #undef __FUNCT__ 489e27a552bSJed Brown #define __FUNCT__ "TSRosWRegister" 490e27a552bSJed Brown /*@C 49161692a83SJed Brown TSRosWRegister - register a Rosenbrock W scheme by providing the entries in the Butcher tableau and optionally embedded approximations and interpolation 492e27a552bSJed Brown 493e27a552bSJed Brown Not Collective, but the same schemes should be registered on all processes on which they will be used 494e27a552bSJed Brown 495e27a552bSJed Brown Input Parameters: 496e27a552bSJed Brown + name - identifier for method 497e27a552bSJed Brown . order - approximation order of method 498e27a552bSJed Brown . s - number of stages, this is the dimension of the matrices below 49961692a83SJed Brown . A - Table of propagated stage coefficients (dimension s*s, row-major), strictly lower triangular 50061692a83SJed Brown . Gamma - Table of coefficients in implicit stage equations (dimension s*s, row-major), lower triangular with nonzero diagonal 501fe7e6d57SJed Brown . b - Step completion table (dimension s) 502fe7e6d57SJed Brown - bembed - Step completion table for a scheme of order one less (dimension s, PETSC_NULL if no embedded scheme is available) 503e27a552bSJed Brown 504e27a552bSJed Brown Notes: 50561692a83SJed Brown Several Rosenbrock W methods are provided, this function is only needed to create new methods. 506e27a552bSJed Brown 507e27a552bSJed Brown Level: advanced 508e27a552bSJed Brown 509e27a552bSJed Brown .keywords: TS, register 510e27a552bSJed Brown 511e27a552bSJed Brown .seealso: TSRosW 512e27a552bSJed Brown @*/ 513e27a552bSJed Brown PetscErrorCode TSRosWRegister(const TSRosWType name,PetscInt order,PetscInt s, 514fe7e6d57SJed Brown const PetscReal A[],const PetscReal Gamma[],const PetscReal b[],const PetscReal bembed[]) 515e27a552bSJed Brown { 516e27a552bSJed Brown PetscErrorCode ierr; 51761692a83SJed Brown RosWTableauLink link; 51861692a83SJed Brown RosWTableau t; 51961692a83SJed Brown PetscInt i,j,k; 52061692a83SJed Brown PetscScalar *GammaInv; 521e27a552bSJed Brown 522e27a552bSJed Brown PetscFunctionBegin; 523fe7e6d57SJed Brown PetscValidCharPointer(name,1); 524fe7e6d57SJed Brown PetscValidPointer(A,4); 525fe7e6d57SJed Brown PetscValidPointer(Gamma,5); 526fe7e6d57SJed Brown PetscValidPointer(b,6); 527fe7e6d57SJed Brown if (bembed) PetscValidPointer(bembed,7); 528fe7e6d57SJed Brown 529e27a552bSJed Brown ierr = PetscMalloc(sizeof(*link),&link);CHKERRQ(ierr); 530e27a552bSJed Brown ierr = PetscMemzero(link,sizeof(*link));CHKERRQ(ierr); 531e27a552bSJed Brown t = &link->tab; 532e27a552bSJed Brown ierr = PetscStrallocpy(name,&t->name);CHKERRQ(ierr); 533e27a552bSJed Brown t->order = order; 534e27a552bSJed Brown t->s = s; 53561692a83SJed Brown ierr = PetscMalloc5(s*s,PetscReal,&t->A,s*s,PetscReal,&t->Gamma,s,PetscReal,&t->b,s,PetscReal,&t->ASum,s,PetscReal,&t->GammaSum);CHKERRQ(ierr); 53643b21953SEmil Constantinescu ierr = PetscMalloc5(s*s,PetscReal,&t->At,s,PetscReal,&t->bt,s*s,PetscReal,&t->GammaInv,s,PetscBool,&t->GammaZeroDiag,s*s,PetscReal,&t->GammaExplicitCorr);CHKERRQ(ierr); 537e27a552bSJed Brown ierr = PetscMemcpy(t->A,A,s*s*sizeof(A[0]));CHKERRQ(ierr); 53861692a83SJed Brown ierr = PetscMemcpy(t->Gamma,Gamma,s*s*sizeof(Gamma[0]));CHKERRQ(ierr); 53943b21953SEmil Constantinescu ierr = PetscMemcpy(t->GammaExplicitCorr,Gamma,s*s*sizeof(Gamma[0]));CHKERRQ(ierr); 54061692a83SJed Brown ierr = PetscMemcpy(t->b,b,s*sizeof(b[0]));CHKERRQ(ierr); 541fe7e6d57SJed Brown if (bembed) { 542fe7e6d57SJed Brown ierr = PetscMalloc2(s,PetscReal,&t->bembed,s,PetscReal,&t->bembedt);CHKERRQ(ierr); 543fe7e6d57SJed Brown ierr = PetscMemcpy(t->bembed,bembed,s*sizeof(bembed[0]));CHKERRQ(ierr); 544fe7e6d57SJed Brown } 54561692a83SJed Brown for (i=0; i<s; i++) { 54661692a83SJed Brown t->ASum[i] = 0; 54761692a83SJed Brown t->GammaSum[i] = 0; 54861692a83SJed Brown for (j=0; j<s; j++) { 54961692a83SJed Brown t->ASum[i] += A[i*s+j]; 550fe7e6d57SJed Brown t->GammaSum[i] += Gamma[i*s+j]; 55161692a83SJed Brown } 55261692a83SJed Brown } 55361692a83SJed Brown ierr = PetscMalloc(s*s*sizeof(PetscScalar),&GammaInv);CHKERRQ(ierr); /* Need to use Scalar for inverse, then convert back to Real */ 55461692a83SJed Brown for (i=0; i<s*s; i++) GammaInv[i] = Gamma[i]; 555fd96d5b0SEmil Constantinescu for (i=0; i<s; i++) { 556fd96d5b0SEmil Constantinescu if (Gamma[i*s+i] == 0.0) { 557fd96d5b0SEmil Constantinescu GammaInv[i*s+i] = 1.0; 558c17803e7SJed Brown t->GammaZeroDiag[i] = PETSC_TRUE; 559fd96d5b0SEmil Constantinescu } else { 560c17803e7SJed Brown t->GammaZeroDiag[i] = PETSC_FALSE; 561fd96d5b0SEmil Constantinescu } 562fd96d5b0SEmil Constantinescu } 563fd96d5b0SEmil Constantinescu 56461692a83SJed Brown switch (s) { 56561692a83SJed Brown case 1: GammaInv[0] = 1./GammaInv[0]; break; 56661692a83SJed Brown case 2: ierr = Kernel_A_gets_inverse_A_2(GammaInv,0);CHKERRQ(ierr); break; 56761692a83SJed Brown case 3: ierr = Kernel_A_gets_inverse_A_3(GammaInv,0);CHKERRQ(ierr); break; 56861692a83SJed Brown case 4: ierr = Kernel_A_gets_inverse_A_4(GammaInv,0);CHKERRQ(ierr); break; 56961692a83SJed Brown case 5: { 57061692a83SJed Brown PetscInt ipvt5[5]; 57161692a83SJed Brown MatScalar work5[5*5]; 57261692a83SJed Brown ierr = Kernel_A_gets_inverse_A_5(GammaInv,ipvt5,work5,0);CHKERRQ(ierr); break; 57361692a83SJed Brown } 57461692a83SJed Brown case 6: ierr = Kernel_A_gets_inverse_A_6(GammaInv,0);CHKERRQ(ierr); break; 57561692a83SJed Brown case 7: ierr = Kernel_A_gets_inverse_A_7(GammaInv,0);CHKERRQ(ierr); break; 57661692a83SJed Brown default: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented for %D stages",s); 57761692a83SJed Brown } 57861692a83SJed Brown for (i=0; i<s*s; i++) t->GammaInv[i] = PetscRealPart(GammaInv[i]); 57961692a83SJed Brown ierr = PetscFree(GammaInv);CHKERRQ(ierr); 58043b21953SEmil Constantinescu 58143b21953SEmil Constantinescu for (i=0; i<s; i++) { 58243b21953SEmil Constantinescu for (k=0; k<i+1; k++) { 58343b21953SEmil Constantinescu t->GammaExplicitCorr[i*s+k]=(t->GammaExplicitCorr[i*s+k])*(t->GammaInv[k*s+k]); 58443b21953SEmil Constantinescu for (j=k+1; j<i+1; j++) { 58543b21953SEmil Constantinescu t->GammaExplicitCorr[i*s+k]+=(t->GammaExplicitCorr[i*s+j])*(t->GammaInv[j*s+k]); 58643b21953SEmil Constantinescu } 58743b21953SEmil Constantinescu } 58843b21953SEmil Constantinescu } 58943b21953SEmil Constantinescu 59061692a83SJed Brown for (i=0; i<s; i++) { 59161692a83SJed Brown for (j=0; j<s; j++) { 59261692a83SJed Brown t->At[i*s+j] = 0; 59361692a83SJed Brown for (k=0; k<s; k++) { 59461692a83SJed Brown t->At[i*s+j] += t->A[i*s+k] * t->GammaInv[k*s+j]; 59561692a83SJed Brown } 59661692a83SJed Brown } 59761692a83SJed Brown t->bt[i] = 0; 59861692a83SJed Brown for (j=0; j<s; j++) { 59961692a83SJed Brown t->bt[i] += t->b[j] * t->GammaInv[j*s+i]; 60061692a83SJed Brown } 601fe7e6d57SJed Brown if (bembed) { 602fe7e6d57SJed Brown t->bembedt[i] = 0; 603fe7e6d57SJed Brown for (j=0; j<s; j++) { 604fe7e6d57SJed Brown t->bembedt[i] += t->bembed[j] * t->GammaInv[j*s+i]; 605fe7e6d57SJed Brown } 606fe7e6d57SJed Brown } 60761692a83SJed Brown } 6088d59e960SJed Brown t->ccfl = 1.0; /* Fix this */ 6098d59e960SJed Brown 61061692a83SJed Brown link->next = RosWTableauList; 61161692a83SJed Brown RosWTableauList = link; 612e27a552bSJed Brown PetscFunctionReturn(0); 613e27a552bSJed Brown } 614e27a552bSJed Brown 615e27a552bSJed Brown #undef __FUNCT__ 6161c3436cfSJed Brown #define __FUNCT__ "TSEvaluateStep_RosW" 6171c3436cfSJed Brown /* 6181c3436cfSJed Brown The step completion formula is 6191c3436cfSJed Brown 6201c3436cfSJed Brown x1 = x0 + b^T Y 6211c3436cfSJed Brown 6221c3436cfSJed Brown where Y is the multi-vector of stages corrections. This function can be called before or after ts->vec_sol has been 6231c3436cfSJed Brown updated. Suppose we have a completion formula b and an embedded formula be of different order. We can write 6241c3436cfSJed Brown 6251c3436cfSJed Brown x1e = x0 + be^T Y 6261c3436cfSJed Brown = x1 - b^T Y + be^T Y 6271c3436cfSJed Brown = x1 + (be - b)^T Y 6281c3436cfSJed Brown 6291c3436cfSJed Brown so we can evaluate the method of different order even after the step has been optimistically completed. 6301c3436cfSJed Brown */ 6311c3436cfSJed Brown static PetscErrorCode TSEvaluateStep_RosW(TS ts,PetscInt order,Vec X,PetscBool *done) 6321c3436cfSJed Brown { 6331c3436cfSJed Brown TS_RosW *ros = (TS_RosW*)ts->data; 6341c3436cfSJed Brown RosWTableau tab = ros->tableau; 6351c3436cfSJed Brown PetscScalar *w = ros->work; 6361c3436cfSJed Brown PetscInt i; 6371c3436cfSJed Brown PetscErrorCode ierr; 6381c3436cfSJed Brown 6391c3436cfSJed Brown PetscFunctionBegin; 6401c3436cfSJed Brown if (order == tab->order) { 641108c343cSJed Brown if (ros->status == TS_STEP_INCOMPLETE) { /* Use standard completion formula */ 6421c3436cfSJed Brown ierr = VecCopy(ts->vec_sol,X);CHKERRQ(ierr); 643de19f811SJed Brown for (i=0; i<tab->s; i++) w[i] = tab->bt[i]; 644de19f811SJed Brown ierr = VecMAXPY(X,tab->s,w,ros->Y);CHKERRQ(ierr); 645108c343cSJed Brown } else {ierr = VecCopy(ts->vec_sol,X);CHKERRQ(ierr);} 6461c3436cfSJed Brown if (done) *done = PETSC_TRUE; 6471c3436cfSJed Brown PetscFunctionReturn(0); 6481c3436cfSJed Brown } else if (order == tab->order-1) { 6491c3436cfSJed Brown if (!tab->bembedt) goto unavailable; 650108c343cSJed Brown if (ros->status == TS_STEP_INCOMPLETE) { /* Use embedded completion formula */ 6511c3436cfSJed Brown ierr = VecCopy(ts->vec_sol,X);CHKERRQ(ierr); 652de19f811SJed Brown for (i=0; i<tab->s; i++) w[i] = tab->bembedt[i]; 653de19f811SJed Brown ierr = VecMAXPY(X,tab->s,w,ros->Y);CHKERRQ(ierr); 654108c343cSJed Brown } else { /* Use rollback-and-recomplete formula (bembedt - bt) */ 655108c343cSJed Brown for (i=0; i<tab->s; i++) w[i] = tab->bembedt[i] - tab->bt[i]; 656108c343cSJed Brown ierr = VecCopy(ts->vec_sol,X);CHKERRQ(ierr); 657108c343cSJed Brown ierr = VecMAXPY(X,tab->s,w,ros->Y);CHKERRQ(ierr); 6581c3436cfSJed Brown } 6591c3436cfSJed Brown if (done) *done = PETSC_TRUE; 6601c3436cfSJed Brown PetscFunctionReturn(0); 6611c3436cfSJed Brown } 6621c3436cfSJed Brown unavailable: 6631c3436cfSJed Brown if (done) *done = PETSC_FALSE; 6641c3436cfSJed Brown else SETERRQ3(((PetscObject)ts)->comm,PETSC_ERR_SUP,"Rosenbrock-W '%s' of order %D cannot evaluate step at order %D",tab->name,tab->order,order); 6651c3436cfSJed Brown PetscFunctionReturn(0); 6661c3436cfSJed Brown } 6671c3436cfSJed Brown 6681c3436cfSJed Brown #undef __FUNCT__ 669e27a552bSJed Brown #define __FUNCT__ "TSStep_RosW" 670e27a552bSJed Brown static PetscErrorCode TSStep_RosW(TS ts) 671e27a552bSJed Brown { 67261692a83SJed Brown TS_RosW *ros = (TS_RosW*)ts->data; 67361692a83SJed Brown RosWTableau tab = ros->tableau; 674e27a552bSJed Brown const PetscInt s = tab->s; 6751c3436cfSJed Brown const PetscReal *At = tab->At,*Gamma = tab->Gamma,*ASum = tab->ASum,*GammaInv = tab->GammaInv; 6760feba352SEmil Constantinescu const PetscReal *GammaExplicitCorr = tab->GammaExplicitCorr; 677c17803e7SJed Brown const PetscBool *GammaZeroDiag = tab->GammaZeroDiag; 67861692a83SJed Brown PetscScalar *w = ros->work; 6797d4bf2deSEmil Constantinescu Vec *Y = ros->Y,Ydot = ros->Ydot,Zdot = ros->Zdot,Zstage = ros->Zstage; 680e27a552bSJed Brown SNES snes; 6811c3436cfSJed Brown TSAdapt adapt; 6821c3436cfSJed Brown PetscInt i,j,its,lits,reject,next_scheme; 683cdbf8f93SLisandro Dalcin PetscReal next_time_step; 6841c3436cfSJed Brown PetscBool accept; 685476b6736SJed Brown SNESConvergedReason snesreason; 686e27a552bSJed Brown PetscErrorCode ierr; 6870feba352SEmil Constantinescu MatStructure str; 688e27a552bSJed Brown 689e27a552bSJed Brown PetscFunctionBegin; 690e27a552bSJed Brown ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 691cdbf8f93SLisandro Dalcin next_time_step = ts->time_step; 6921c3436cfSJed Brown accept = PETSC_TRUE; 693108c343cSJed Brown ros->status = TS_STEP_INCOMPLETE; 694e27a552bSJed Brown 6951c3436cfSJed Brown for (reject=0; reject<ts->max_reject; reject++,ts->reject++) { 6961c3436cfSJed Brown const PetscReal h = ts->time_step; 697e27a552bSJed Brown for (i=0; i<s; i++) { 6981c3436cfSJed Brown ros->stage_time = ts->ptime + h*ASum[i]; 699c17803e7SJed Brown if (GammaZeroDiag[i]) { 700c17803e7SJed Brown ros->stage_explicit = PETSC_TRUE; 701fd96d5b0SEmil Constantinescu ros->shift = 1./h; 702c17803e7SJed Brown } else { 703c17803e7SJed Brown ros->stage_explicit = PETSC_FALSE; 70461692a83SJed Brown ros->shift = 1./(h*Gamma[i*s+i]); 705fd96d5b0SEmil Constantinescu } 70661692a83SJed Brown 70761692a83SJed Brown ierr = VecCopy(ts->vec_sol,Zstage);CHKERRQ(ierr); 708de19f811SJed Brown for (j=0; j<i; j++) w[j] = At[i*s+j]; 709de19f811SJed Brown ierr = VecMAXPY(Zstage,i,w,Y);CHKERRQ(ierr); 71061692a83SJed Brown 71161692a83SJed Brown for (j=0; j<i; j++) w[j] = 1./h * GammaInv[i*s+j]; 71261692a83SJed Brown ierr = VecZeroEntries(Zdot);CHKERRQ(ierr); 71361692a83SJed Brown ierr = VecMAXPY(Zdot,i,w,Y);CHKERRQ(ierr); 71461692a83SJed Brown 715e27a552bSJed Brown /* Initial guess taken from last stage */ 71661692a83SJed Brown ierr = VecZeroEntries(Y[i]);CHKERRQ(ierr); 71761692a83SJed Brown 7187d4bf2deSEmil Constantinescu if (!ros->stage_explicit) { 71961692a83SJed Brown if (!ros->recompute_jacobian && !i) { 72061692a83SJed Brown ierr = SNESSetLagJacobian(snes,-2);CHKERRQ(ierr); /* Recompute the Jacobian on this solve, but not again */ 72161692a83SJed Brown } 72261692a83SJed Brown ierr = SNESSolve(snes,PETSC_NULL,Y[i]);CHKERRQ(ierr); 723e27a552bSJed Brown ierr = SNESGetIterationNumber(snes,&its);CHKERRQ(ierr); 724e27a552bSJed Brown ierr = SNESGetLinearSolveIterations(snes,&lits);CHKERRQ(ierr); 725476b6736SJed Brown ierr = SNESGetConvergedReason(snes,&snesreason);CHKERRQ(ierr); 726e27a552bSJed Brown ts->nonlinear_its += its; ts->linear_its += lits; 727476b6736SJed Brown if (snesreason < 0) { 728476b6736SJed Brown if (ts->max_snes_failures > 0 && ++ts->num_snes_failures >= ts->max_snes_failures) { 729476b6736SJed Brown ts->reason = TS_DIVERGED_NONLINEAR_SOLVE; 730476b6736SJed Brown ierr = PetscInfo2(ts,"Step=%D, nonlinear solve solve failures %D greater than current TS allowed, stopping solve\n",ts->steps,ts->num_snes_failures);CHKERRQ(ierr); 731476b6736SJed Brown PetscFunctionReturn(0); 732476b6736SJed Brown } else { 733476b6736SJed Brown ts->time_step *= ts->scale_solve_failed; 734476b6736SJed Brown goto reject_step; /* Do not try to solve any more stages */ 735476b6736SJed Brown } 736476b6736SJed Brown } 7377d4bf2deSEmil Constantinescu } else { 7381ce71dffSSatish Balay Mat J,Jp; 7390feba352SEmil Constantinescu ierr = VecZeroEntries(Ydot);CHKERRQ(ierr); /* Evaluate Y[i]=G(t,Ydot=0,Zstage) */ 7400feba352SEmil Constantinescu ierr = TSComputeIFunction(ts,ros->stage_time,Zstage,Ydot,Y[i],PETSC_FALSE);CHKERRQ(ierr); 7410feba352SEmil Constantinescu ierr = VecScale(Y[i],-1.0); 7420feba352SEmil Constantinescu ierr = VecAXPY(Y[i],-1.0,Zdot);CHKERRQ(ierr); /*Y[i]=F(Zstage)-Zdot[=GammaInv*Y]*/ 7430feba352SEmil Constantinescu 7440feba352SEmil Constantinescu ierr = VecZeroEntries(Zstage);CHKERRQ(ierr); /* Zstage = GammaExplicitCorr[i,j] * Y[j] */ 7450feba352SEmil Constantinescu for (j=0; j<i; j++) w[j] = GammaExplicitCorr[i*s+j]; 7460feba352SEmil Constantinescu ierr = VecMAXPY(Zstage,i,w,Y);CHKERRQ(ierr); 7470feba352SEmil Constantinescu /*Y[i] += Y[i] + Jac*Zstage[=Jac*GammaExplicitCorr[i,j] * Y[j]] */ 7480feba352SEmil Constantinescu str = SAME_NONZERO_PATTERN; 7490feba352SEmil Constantinescu ierr = TSGetIJacobian(ts,&J,&Jp,PETSC_NULL,PETSC_NULL); 7500feba352SEmil Constantinescu ierr = TSComputeIJacobian(ts,ros->stage_time,ts->vec_sol,Ydot,0,&J,&Jp,&str,PETSC_FALSE);CHKERRQ(ierr); 7510feba352SEmil Constantinescu ierr = MatMult(J,Zstage,Zdot); 7520feba352SEmil Constantinescu 7530feba352SEmil Constantinescu ierr = VecAXPY(Y[i],-1.0,Zdot);CHKERRQ(ierr); 7540feba352SEmil Constantinescu ierr = VecScale(Y[i],h); 7557d4bf2deSEmil Constantinescu ts->linear_its += 1; 7567d4bf2deSEmil Constantinescu } 757e27a552bSJed Brown } 7581c3436cfSJed Brown ierr = TSEvaluateStep(ts,tab->order,ts->vec_sol,PETSC_NULL);CHKERRQ(ierr); 759108c343cSJed Brown ros->status = TS_STEP_PENDING; 760e27a552bSJed Brown 7611c3436cfSJed Brown /* Register only the current method as a candidate because we're not supporting multiple candidates yet. */ 7621c3436cfSJed Brown ierr = TSGetAdapt(ts,&adapt);CHKERRQ(ierr); 7631c3436cfSJed Brown ierr = TSAdaptCandidatesClear(adapt);CHKERRQ(ierr); 7648d59e960SJed Brown ierr = TSAdaptCandidateAdd(adapt,tab->name,tab->order,1,tab->ccfl,1.*tab->s,PETSC_TRUE);CHKERRQ(ierr); 7651c3436cfSJed Brown ierr = TSAdaptChoose(adapt,ts,ts->time_step,&next_scheme,&next_time_step,&accept);CHKERRQ(ierr); 7661c3436cfSJed Brown if (accept) { 7671c3436cfSJed Brown /* ignore next_scheme for now */ 768e27a552bSJed Brown ts->ptime += ts->time_step; 769cdbf8f93SLisandro Dalcin ts->time_step = next_time_step; 770e27a552bSJed Brown ts->steps++; 771108c343cSJed Brown ros->status = TS_STEP_COMPLETE; 7721c3436cfSJed Brown break; 7731c3436cfSJed Brown } else { /* Roll back the current step */ 7741c3436cfSJed Brown for (i=0; i<s; i++) w[i] = -tab->bt[i]; 7751c3436cfSJed Brown ierr = VecMAXPY(ts->vec_sol,s,w,Y);CHKERRQ(ierr); 7761c3436cfSJed Brown ts->time_step = next_time_step; 777108c343cSJed Brown ros->status = TS_STEP_INCOMPLETE; 7781c3436cfSJed Brown } 779476b6736SJed Brown reject_step: continue; 7801c3436cfSJed Brown } 781476b6736SJed Brown ts->reason = TS_DIVERGED_STEP_REJECTED; 782e27a552bSJed Brown PetscFunctionReturn(0); 783e27a552bSJed Brown } 784e27a552bSJed Brown 785e27a552bSJed Brown #undef __FUNCT__ 786e27a552bSJed Brown #define __FUNCT__ "TSInterpolate_RosW" 787e27a552bSJed Brown static PetscErrorCode TSInterpolate_RosW(TS ts,PetscReal itime,Vec X) 788e27a552bSJed Brown { 78961692a83SJed Brown TS_RosW *ros = (TS_RosW*)ts->data; 790e27a552bSJed Brown 791e27a552bSJed Brown PetscFunctionBegin; 79261692a83SJed Brown SETERRQ1(((PetscObject)ts)->comm,PETSC_ERR_SUP,"TSRosW %s does not have an interpolation formula",ros->tableau->name); 793e27a552bSJed Brown PetscFunctionReturn(0); 794e27a552bSJed Brown } 795e27a552bSJed Brown 796e27a552bSJed Brown /*------------------------------------------------------------*/ 797e27a552bSJed Brown #undef __FUNCT__ 798e27a552bSJed Brown #define __FUNCT__ "TSReset_RosW" 799e27a552bSJed Brown static PetscErrorCode TSReset_RosW(TS ts) 800e27a552bSJed Brown { 80161692a83SJed Brown TS_RosW *ros = (TS_RosW*)ts->data; 802e27a552bSJed Brown PetscInt s; 803e27a552bSJed Brown PetscErrorCode ierr; 804e27a552bSJed Brown 805e27a552bSJed Brown PetscFunctionBegin; 80661692a83SJed Brown if (!ros->tableau) PetscFunctionReturn(0); 80761692a83SJed Brown s = ros->tableau->s; 80861692a83SJed Brown ierr = VecDestroyVecs(s,&ros->Y);CHKERRQ(ierr); 80961692a83SJed Brown ierr = VecDestroy(&ros->Ydot);CHKERRQ(ierr); 81061692a83SJed Brown ierr = VecDestroy(&ros->Ystage);CHKERRQ(ierr); 81161692a83SJed Brown ierr = VecDestroy(&ros->Zdot);CHKERRQ(ierr); 81261692a83SJed Brown ierr = VecDestroy(&ros->Zstage);CHKERRQ(ierr); 81361692a83SJed Brown ierr = PetscFree(ros->work);CHKERRQ(ierr); 814e27a552bSJed Brown PetscFunctionReturn(0); 815e27a552bSJed Brown } 816e27a552bSJed Brown 817e27a552bSJed Brown #undef __FUNCT__ 818e27a552bSJed Brown #define __FUNCT__ "TSDestroy_RosW" 819e27a552bSJed Brown static PetscErrorCode TSDestroy_RosW(TS ts) 820e27a552bSJed Brown { 821e27a552bSJed Brown PetscErrorCode ierr; 822e27a552bSJed Brown 823e27a552bSJed Brown PetscFunctionBegin; 824e27a552bSJed Brown ierr = TSReset_RosW(ts);CHKERRQ(ierr); 825e27a552bSJed Brown ierr = PetscFree(ts->data);CHKERRQ(ierr); 826e27a552bSJed Brown ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSRosWGetType_C","",PETSC_NULL);CHKERRQ(ierr); 827e27a552bSJed Brown ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSRosWSetType_C","",PETSC_NULL);CHKERRQ(ierr); 82861692a83SJed Brown ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSRosWSetRecomputeJacobian_C","",PETSC_NULL);CHKERRQ(ierr); 829e27a552bSJed Brown PetscFunctionReturn(0); 830e27a552bSJed Brown } 831e27a552bSJed Brown 832e27a552bSJed Brown /* 833e27a552bSJed Brown This defines the nonlinear equation that is to be solved with SNES 834e27a552bSJed Brown G(U) = F[t0+Theta*dt, U, (U-U0)*shift] = 0 835e27a552bSJed Brown */ 836e27a552bSJed Brown #undef __FUNCT__ 837e27a552bSJed Brown #define __FUNCT__ "SNESTSFormFunction_RosW" 838e27a552bSJed Brown static PetscErrorCode SNESTSFormFunction_RosW(SNES snes,Vec X,Vec F,TS ts) 839e27a552bSJed Brown { 84061692a83SJed Brown TS_RosW *ros = (TS_RosW*)ts->data; 841e27a552bSJed Brown PetscErrorCode ierr; 842e27a552bSJed Brown 843e27a552bSJed Brown PetscFunctionBegin; 84461692a83SJed Brown ierr = VecWAXPY(ros->Ydot,ros->shift,X,ros->Zdot);CHKERRQ(ierr); /* Ydot = shift*X + Zdot */ 84561692a83SJed Brown ierr = VecWAXPY(ros->Ystage,1.0,X,ros->Zstage);CHKERRQ(ierr); /* Ystage = X + Zstage */ 84661692a83SJed Brown ierr = TSComputeIFunction(ts,ros->stage_time,ros->Ystage,ros->Ydot,F,PETSC_FALSE);CHKERRQ(ierr); 847e27a552bSJed Brown PetscFunctionReturn(0); 848e27a552bSJed Brown } 849e27a552bSJed Brown 850e27a552bSJed Brown #undef __FUNCT__ 851e27a552bSJed Brown #define __FUNCT__ "SNESTSFormJacobian_RosW" 852e27a552bSJed Brown static PetscErrorCode SNESTSFormJacobian_RosW(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *str,TS ts) 853e27a552bSJed Brown { 85461692a83SJed Brown TS_RosW *ros = (TS_RosW*)ts->data; 855e27a552bSJed Brown PetscErrorCode ierr; 856e27a552bSJed Brown 857e27a552bSJed Brown PetscFunctionBegin; 85861692a83SJed Brown /* ros->Ydot and ros->Ystage have already been computed in SNESTSFormFunction_RosW (SNES guarantees this) */ 85961692a83SJed Brown ierr = TSComputeIJacobian(ts,ros->stage_time,ros->Ystage,ros->Ydot,ros->shift,A,B,str,PETSC_TRUE);CHKERRQ(ierr); 860e27a552bSJed Brown PetscFunctionReturn(0); 861e27a552bSJed Brown } 862e27a552bSJed Brown 863e27a552bSJed Brown #undef __FUNCT__ 864e27a552bSJed Brown #define __FUNCT__ "TSSetUp_RosW" 865e27a552bSJed Brown static PetscErrorCode TSSetUp_RosW(TS ts) 866e27a552bSJed Brown { 86761692a83SJed Brown TS_RosW *ros = (TS_RosW*)ts->data; 86861692a83SJed Brown RosWTableau tab = ros->tableau; 869e27a552bSJed Brown PetscInt s = tab->s; 870e27a552bSJed Brown PetscErrorCode ierr; 871e27a552bSJed Brown 872e27a552bSJed Brown PetscFunctionBegin; 87361692a83SJed Brown if (!ros->tableau) { 874e27a552bSJed Brown ierr = TSRosWSetType(ts,TSRosWDefault);CHKERRQ(ierr); 875e27a552bSJed Brown } 87661692a83SJed Brown ierr = VecDuplicateVecs(ts->vec_sol,s,&ros->Y);CHKERRQ(ierr); 87761692a83SJed Brown ierr = VecDuplicate(ts->vec_sol,&ros->Ydot);CHKERRQ(ierr); 87861692a83SJed Brown ierr = VecDuplicate(ts->vec_sol,&ros->Ystage);CHKERRQ(ierr); 87961692a83SJed Brown ierr = VecDuplicate(ts->vec_sol,&ros->Zdot);CHKERRQ(ierr); 88061692a83SJed Brown ierr = VecDuplicate(ts->vec_sol,&ros->Zstage);CHKERRQ(ierr); 88161692a83SJed Brown ierr = PetscMalloc(s*sizeof(ros->work[0]),&ros->work);CHKERRQ(ierr); 882e27a552bSJed Brown PetscFunctionReturn(0); 883e27a552bSJed Brown } 884e27a552bSJed Brown /*------------------------------------------------------------*/ 885e27a552bSJed Brown 886e27a552bSJed Brown #undef __FUNCT__ 887e27a552bSJed Brown #define __FUNCT__ "TSSetFromOptions_RosW" 888e27a552bSJed Brown static PetscErrorCode TSSetFromOptions_RosW(TS ts) 889e27a552bSJed Brown { 89061692a83SJed Brown TS_RosW *ros = (TS_RosW*)ts->data; 891e27a552bSJed Brown PetscErrorCode ierr; 89261692a83SJed Brown char rostype[256]; 893e27a552bSJed Brown 894e27a552bSJed Brown PetscFunctionBegin; 895e27a552bSJed Brown ierr = PetscOptionsHead("RosW ODE solver options");CHKERRQ(ierr); 896e27a552bSJed Brown { 89761692a83SJed Brown RosWTableauLink link; 898e27a552bSJed Brown PetscInt count,choice; 899e27a552bSJed Brown PetscBool flg; 900e27a552bSJed Brown const char **namelist; 90161692a83SJed Brown SNES snes; 90261692a83SJed Brown 90361692a83SJed Brown ierr = PetscStrncpy(rostype,TSRosWDefault,sizeof rostype);CHKERRQ(ierr); 90461692a83SJed Brown for (link=RosWTableauList,count=0; link; link=link->next,count++) ; 905e27a552bSJed Brown ierr = PetscMalloc(count*sizeof(char*),&namelist);CHKERRQ(ierr); 90661692a83SJed Brown for (link=RosWTableauList,count=0; link; link=link->next,count++) namelist[count] = link->tab.name; 90761692a83SJed Brown ierr = PetscOptionsEList("-ts_rosw_type","Family of Rosenbrock-W method","TSRosWSetType",(const char*const*)namelist,count,rostype,&choice,&flg);CHKERRQ(ierr); 90861692a83SJed Brown ierr = TSRosWSetType(ts,flg ? namelist[choice] : rostype);CHKERRQ(ierr); 909e27a552bSJed Brown ierr = PetscFree(namelist);CHKERRQ(ierr); 91061692a83SJed Brown 91161692a83SJed Brown ierr = PetscOptionsBool("-ts_rosw_recompute_jacobian","Recompute the Jacobian at each stage","TSRosWSetRecomputeJacobian",ros->recompute_jacobian,&ros->recompute_jacobian,PETSC_NULL);CHKERRQ(ierr); 91261692a83SJed Brown 91361692a83SJed Brown /* Rosenbrock methods are linearly implicit, so set that unless the user has specifically asked for something else */ 91461692a83SJed Brown ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 91561692a83SJed Brown if (!((PetscObject)snes)->type_name) { 91661692a83SJed Brown ierr = SNESSetType(snes,SNESKSPONLY);CHKERRQ(ierr); 91761692a83SJed Brown } 91861692a83SJed Brown ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); 919e27a552bSJed Brown } 920e27a552bSJed Brown ierr = PetscOptionsTail();CHKERRQ(ierr); 921e27a552bSJed Brown PetscFunctionReturn(0); 922e27a552bSJed Brown } 923e27a552bSJed Brown 924e27a552bSJed Brown #undef __FUNCT__ 925e27a552bSJed Brown #define __FUNCT__ "PetscFormatRealArray" 926e27a552bSJed Brown static PetscErrorCode PetscFormatRealArray(char buf[],size_t len,const char *fmt,PetscInt n,const PetscReal x[]) 927e27a552bSJed Brown { 928e27a552bSJed Brown PetscErrorCode ierr; 929e408995aSJed Brown PetscInt i; 930e408995aSJed Brown size_t left,count; 931e27a552bSJed Brown char *p; 932e27a552bSJed Brown 933e27a552bSJed Brown PetscFunctionBegin; 934e408995aSJed Brown for (i=0,p=buf,left=len; i<n; i++) { 935e408995aSJed Brown ierr = PetscSNPrintfCount(p,left,fmt,&count,x[i]);CHKERRQ(ierr); 936e27a552bSJed Brown if (count >= left) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Insufficient space in buffer"); 937e27a552bSJed Brown left -= count; 938e27a552bSJed Brown p += count; 939e27a552bSJed Brown *p++ = ' '; 940e27a552bSJed Brown } 941e27a552bSJed Brown p[i ? 0 : -1] = 0; 942e27a552bSJed Brown PetscFunctionReturn(0); 943e27a552bSJed Brown } 944e27a552bSJed Brown 945e27a552bSJed Brown #undef __FUNCT__ 946e27a552bSJed Brown #define __FUNCT__ "TSView_RosW" 947e27a552bSJed Brown static PetscErrorCode TSView_RosW(TS ts,PetscViewer viewer) 948e27a552bSJed Brown { 94961692a83SJed Brown TS_RosW *ros = (TS_RosW*)ts->data; 95061692a83SJed Brown RosWTableau tab = ros->tableau; 951e27a552bSJed Brown PetscBool iascii; 952e27a552bSJed Brown PetscErrorCode ierr; 953e27a552bSJed Brown 954e27a552bSJed Brown PetscFunctionBegin; 955e27a552bSJed Brown ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 956e27a552bSJed Brown if (iascii) { 95761692a83SJed Brown const TSRosWType rostype; 958e408995aSJed Brown PetscInt i; 959e408995aSJed Brown PetscReal abscissa[512]; 960e27a552bSJed Brown char buf[512]; 96161692a83SJed Brown ierr = TSRosWGetType(ts,&rostype);CHKERRQ(ierr); 96261692a83SJed Brown ierr = PetscViewerASCIIPrintf(viewer," Rosenbrock-W %s\n",rostype);CHKERRQ(ierr); 963e408995aSJed Brown ierr = PetscFormatRealArray(buf,sizeof buf,"% 8.6f",tab->s,tab->ASum);CHKERRQ(ierr); 96461692a83SJed Brown ierr = PetscViewerASCIIPrintf(viewer," Abscissa of A = %s\n",buf);CHKERRQ(ierr); 965e408995aSJed Brown for (i=0; i<tab->s; i++) abscissa[i] = tab->ASum[i] + tab->Gamma[i]; 966e408995aSJed Brown ierr = PetscFormatRealArray(buf,sizeof buf,"% 8.6f",tab->s,abscissa);CHKERRQ(ierr); 967e408995aSJed Brown ierr = PetscViewerASCIIPrintf(viewer," Abscissa of A+Gamma = %s\n",buf);CHKERRQ(ierr); 968e27a552bSJed Brown } 969e27a552bSJed Brown ierr = SNESView(ts->snes,viewer);CHKERRQ(ierr); 970e27a552bSJed Brown PetscFunctionReturn(0); 971e27a552bSJed Brown } 972e27a552bSJed Brown 973e27a552bSJed Brown #undef __FUNCT__ 974e27a552bSJed Brown #define __FUNCT__ "TSRosWSetType" 975e27a552bSJed Brown /*@C 97661692a83SJed Brown TSRosWSetType - Set the type of Rosenbrock-W scheme 977e27a552bSJed Brown 978e27a552bSJed Brown Logically collective 979e27a552bSJed Brown 980e27a552bSJed Brown Input Parameter: 981e27a552bSJed Brown + ts - timestepping context 98261692a83SJed Brown - rostype - type of Rosenbrock-W scheme 983e27a552bSJed Brown 984020d8f30SJed Brown Level: beginner 985e27a552bSJed Brown 986020d8f30SJed Brown .seealso: TSRosWGetType(), TSROSW, TSROSW2M, TSROSW2P, TSROSWRA3PW, TSROSWRA34PW2, TSROSWRODAS3, TSROSWSANDU3, TSROSWASSP3P3S1C, TSROSWLASSP3P4S2C, TSROSWLLSSP3P4S2C, TSROSWARK3 987e27a552bSJed Brown @*/ 98861692a83SJed Brown PetscErrorCode TSRosWSetType(TS ts,const TSRosWType rostype) 989e27a552bSJed Brown { 990e27a552bSJed Brown PetscErrorCode ierr; 991e27a552bSJed Brown 992e27a552bSJed Brown PetscFunctionBegin; 993e27a552bSJed Brown PetscValidHeaderSpecific(ts,TS_CLASSID,1); 99461692a83SJed Brown ierr = PetscTryMethod(ts,"TSRosWSetType_C",(TS,const TSRosWType),(ts,rostype));CHKERRQ(ierr); 995e27a552bSJed Brown PetscFunctionReturn(0); 996e27a552bSJed Brown } 997e27a552bSJed Brown 998e27a552bSJed Brown #undef __FUNCT__ 999e27a552bSJed Brown #define __FUNCT__ "TSRosWGetType" 1000e27a552bSJed Brown /*@C 100161692a83SJed Brown TSRosWGetType - Get the type of Rosenbrock-W scheme 1002e27a552bSJed Brown 1003e27a552bSJed Brown Logically collective 1004e27a552bSJed Brown 1005e27a552bSJed Brown Input Parameter: 1006e27a552bSJed Brown . ts - timestepping context 1007e27a552bSJed Brown 1008e27a552bSJed Brown Output Parameter: 100961692a83SJed Brown . rostype - type of Rosenbrock-W scheme 1010e27a552bSJed Brown 1011e27a552bSJed Brown Level: intermediate 1012e27a552bSJed Brown 1013e27a552bSJed Brown .seealso: TSRosWGetType() 1014e27a552bSJed Brown @*/ 101561692a83SJed Brown PetscErrorCode TSRosWGetType(TS ts,const TSRosWType *rostype) 1016e27a552bSJed Brown { 1017e27a552bSJed Brown PetscErrorCode ierr; 1018e27a552bSJed Brown 1019e27a552bSJed Brown PetscFunctionBegin; 1020e27a552bSJed Brown PetscValidHeaderSpecific(ts,TS_CLASSID,1); 102161692a83SJed Brown ierr = PetscUseMethod(ts,"TSRosWGetType_C",(TS,const TSRosWType*),(ts,rostype));CHKERRQ(ierr); 1022e27a552bSJed Brown PetscFunctionReturn(0); 1023e27a552bSJed Brown } 1024e27a552bSJed Brown 1025e27a552bSJed Brown #undef __FUNCT__ 102661692a83SJed Brown #define __FUNCT__ "TSRosWSetRecomputeJacobian" 1027e27a552bSJed Brown /*@C 102861692a83SJed Brown TSRosWSetRecomputeJacobian - Set whether to recompute the Jacobian at each stage. The default is to update the Jacobian once per step. 1029e27a552bSJed Brown 1030e27a552bSJed Brown Logically collective 1031e27a552bSJed Brown 1032e27a552bSJed Brown Input Parameter: 1033e27a552bSJed Brown + ts - timestepping context 103461692a83SJed Brown - flg - PETSC_TRUE to recompute the Jacobian at each stage 1035e27a552bSJed Brown 1036e27a552bSJed Brown Level: intermediate 1037e27a552bSJed Brown 1038e27a552bSJed Brown .seealso: TSRosWGetType() 1039e27a552bSJed Brown @*/ 104061692a83SJed Brown PetscErrorCode TSRosWSetRecomputeJacobian(TS ts,PetscBool flg) 1041e27a552bSJed Brown { 1042e27a552bSJed Brown PetscErrorCode ierr; 1043e27a552bSJed Brown 1044e27a552bSJed Brown PetscFunctionBegin; 1045e27a552bSJed Brown PetscValidHeaderSpecific(ts,TS_CLASSID,1); 104661692a83SJed Brown ierr = PetscTryMethod(ts,"TSRosWSetRecomputeJacobian_C",(TS,PetscBool),(ts,flg));CHKERRQ(ierr); 1047e27a552bSJed Brown PetscFunctionReturn(0); 1048e27a552bSJed Brown } 1049e27a552bSJed Brown 1050e27a552bSJed Brown EXTERN_C_BEGIN 1051e27a552bSJed Brown #undef __FUNCT__ 1052e27a552bSJed Brown #define __FUNCT__ "TSRosWGetType_RosW" 105361692a83SJed Brown PetscErrorCode TSRosWGetType_RosW(TS ts,const TSRosWType *rostype) 1054e27a552bSJed Brown { 105561692a83SJed Brown TS_RosW *ros = (TS_RosW*)ts->data; 1056e27a552bSJed Brown PetscErrorCode ierr; 1057e27a552bSJed Brown 1058e27a552bSJed Brown PetscFunctionBegin; 105961692a83SJed Brown if (!ros->tableau) {ierr = TSRosWSetType(ts,TSRosWDefault);CHKERRQ(ierr);} 106061692a83SJed Brown *rostype = ros->tableau->name; 1061e27a552bSJed Brown PetscFunctionReturn(0); 1062e27a552bSJed Brown } 1063e27a552bSJed Brown #undef __FUNCT__ 1064e27a552bSJed Brown #define __FUNCT__ "TSRosWSetType_RosW" 106561692a83SJed Brown PetscErrorCode TSRosWSetType_RosW(TS ts,const TSRosWType rostype) 1066e27a552bSJed Brown { 106761692a83SJed Brown TS_RosW *ros = (TS_RosW*)ts->data; 1068e27a552bSJed Brown PetscErrorCode ierr; 1069e27a552bSJed Brown PetscBool match; 107061692a83SJed Brown RosWTableauLink link; 1071e27a552bSJed Brown 1072e27a552bSJed Brown PetscFunctionBegin; 107361692a83SJed Brown if (ros->tableau) { 107461692a83SJed Brown ierr = PetscStrcmp(ros->tableau->name,rostype,&match);CHKERRQ(ierr); 1075e27a552bSJed Brown if (match) PetscFunctionReturn(0); 1076e27a552bSJed Brown } 107761692a83SJed Brown for (link = RosWTableauList; link; link=link->next) { 107861692a83SJed Brown ierr = PetscStrcmp(link->tab.name,rostype,&match);CHKERRQ(ierr); 1079e27a552bSJed Brown if (match) { 1080e27a552bSJed Brown ierr = TSReset_RosW(ts);CHKERRQ(ierr); 108161692a83SJed Brown ros->tableau = &link->tab; 1082e27a552bSJed Brown PetscFunctionReturn(0); 1083e27a552bSJed Brown } 1084e27a552bSJed Brown } 108561692a83SJed Brown SETERRQ1(((PetscObject)ts)->comm,PETSC_ERR_ARG_UNKNOWN_TYPE,"Could not find '%s'",rostype); 1086e27a552bSJed Brown PetscFunctionReturn(0); 1087e27a552bSJed Brown } 108861692a83SJed Brown 1089e27a552bSJed Brown #undef __FUNCT__ 109061692a83SJed Brown #define __FUNCT__ "TSRosWSetRecomputeJacobian_RosW" 109161692a83SJed Brown PetscErrorCode TSRosWSetRecomputeJacobian_RosW(TS ts,PetscBool flg) 1092e27a552bSJed Brown { 109361692a83SJed Brown TS_RosW *ros = (TS_RosW*)ts->data; 1094e27a552bSJed Brown 1095e27a552bSJed Brown PetscFunctionBegin; 109661692a83SJed Brown ros->recompute_jacobian = flg; 1097e27a552bSJed Brown PetscFunctionReturn(0); 1098e27a552bSJed Brown } 1099e27a552bSJed Brown EXTERN_C_END 1100e27a552bSJed Brown 1101e27a552bSJed Brown /* ------------------------------------------------------------ */ 1102e27a552bSJed Brown /*MC 1103020d8f30SJed Brown TSROSW - ODE solver using Rosenbrock-W schemes 1104e27a552bSJed Brown 1105e27a552bSJed Brown These methods are intended for problems with well-separated time scales, especially when a slow scale is strongly 1106e27a552bSJed Brown nonlinear such that it is expensive to solve with a fully implicit method. The user should provide the stiff part 1107e27a552bSJed Brown of the equation using TSSetIFunction() and the non-stiff part with TSSetRHSFunction(). 1108e27a552bSJed Brown 1109e27a552bSJed Brown Notes: 111061692a83SJed Brown This method currently only works with autonomous ODE and DAE. 111161692a83SJed Brown 111261692a83SJed Brown Developer notes: 111361692a83SJed Brown Rosenbrock-W methods are typically specified for autonomous ODE 111461692a83SJed Brown 111561692a83SJed Brown $ xdot = f(x) 111661692a83SJed Brown 111761692a83SJed Brown by the stage equations 111861692a83SJed Brown 111961692a83SJed Brown $ k_i = h f(x_0 + sum_j alpha_ij k_j) + h J sum_j gamma_ij k_j 112061692a83SJed Brown 112161692a83SJed Brown and step completion formula 112261692a83SJed Brown 112361692a83SJed Brown $ x_1 = x_0 + sum_j b_j k_j 112461692a83SJed Brown 112561692a83SJed Brown with step size h and coefficients alpha_ij, gamma_ij, and b_i. Implementing the method in this form would require f(x) 112661692a83SJed Brown and the Jacobian J to be available, in addition to the shifted matrix I - h gamma_ii J. Following Hairer and Wanner, 112761692a83SJed Brown we define new variables for the stage equations 112861692a83SJed Brown 112961692a83SJed Brown $ y_i = gamma_ij k_j 113061692a83SJed Brown 113161692a83SJed Brown The k_j can be recovered because Gamma is invertible. Let C be the lower triangular part of Gamma^{-1} and define 113261692a83SJed Brown 113361692a83SJed Brown $ A = Alpha Gamma^{-1}, bt^T = b^T Gamma^{-i} 113461692a83SJed Brown 113561692a83SJed Brown to rewrite the method as 113661692a83SJed Brown 113761692a83SJed Brown $ [M/(h gamma_ii) - J] y_i = f(x_0 + sum_j a_ij y_j) + M sum_j (c_ij/h) y_j 113861692a83SJed Brown $ x_1 = x_0 + sum_j bt_j y_j 113961692a83SJed Brown 114061692a83SJed Brown where we have introduced the mass matrix M. Continue by defining 114161692a83SJed Brown 114261692a83SJed Brown $ ydot_i = 1/(h gamma_ii) y_i - sum_j (c_ij/h) y_j 114361692a83SJed Brown 114461692a83SJed Brown or, more compactly in tensor notation 114561692a83SJed Brown 114661692a83SJed Brown $ Ydot = 1/h (Gamma^{-1} \otimes I) Y . 114761692a83SJed Brown 114861692a83SJed Brown Note that Gamma^{-1} is lower triangular. With this definition of Ydot in terms of known quantities and the current 114961692a83SJed Brown stage y_i, the stage equations reduce to performing one Newton step (typically with a lagged Jacobian) on the 115061692a83SJed Brown equation 115161692a83SJed Brown 115261692a83SJed Brown $ g(x_0 + sum_j a_ij y_j + y_i, ydot_i) = 0 115361692a83SJed Brown 115461692a83SJed Brown with initial guess y_i = 0. 1155e27a552bSJed Brown 1156e27a552bSJed Brown Level: beginner 1157e27a552bSJed Brown 1158020d8f30SJed Brown .seealso: TSCreate(), TS, TSSetType(), TSRosWSetType(), TSRosWRegister() 1159e27a552bSJed Brown 1160e27a552bSJed Brown M*/ 1161e27a552bSJed Brown EXTERN_C_BEGIN 1162e27a552bSJed Brown #undef __FUNCT__ 1163e27a552bSJed Brown #define __FUNCT__ "TSCreate_RosW" 1164e27a552bSJed Brown PetscErrorCode TSCreate_RosW(TS ts) 1165e27a552bSJed Brown { 116661692a83SJed Brown TS_RosW *ros; 1167e27a552bSJed Brown PetscErrorCode ierr; 1168e27a552bSJed Brown 1169e27a552bSJed Brown PetscFunctionBegin; 1170e27a552bSJed Brown #if !defined(PETSC_USE_DYNAMIC_LIBRARIES) 1171e27a552bSJed Brown ierr = TSRosWInitializePackage(PETSC_NULL);CHKERRQ(ierr); 1172e27a552bSJed Brown #endif 1173e27a552bSJed Brown 1174e27a552bSJed Brown ts->ops->reset = TSReset_RosW; 1175e27a552bSJed Brown ts->ops->destroy = TSDestroy_RosW; 1176e27a552bSJed Brown ts->ops->view = TSView_RosW; 1177e27a552bSJed Brown ts->ops->setup = TSSetUp_RosW; 1178e27a552bSJed Brown ts->ops->step = TSStep_RosW; 1179e27a552bSJed Brown ts->ops->interpolate = TSInterpolate_RosW; 11801c3436cfSJed Brown ts->ops->evaluatestep = TSEvaluateStep_RosW; 1181e27a552bSJed Brown ts->ops->setfromoptions = TSSetFromOptions_RosW; 1182e27a552bSJed Brown ts->ops->snesfunction = SNESTSFormFunction_RosW; 1183e27a552bSJed Brown ts->ops->snesjacobian = SNESTSFormJacobian_RosW; 1184e27a552bSJed Brown 118561692a83SJed Brown ierr = PetscNewLog(ts,TS_RosW,&ros);CHKERRQ(ierr); 118661692a83SJed Brown ts->data = (void*)ros; 1187e27a552bSJed Brown 1188e27a552bSJed Brown ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSRosWGetType_C","TSRosWGetType_RosW",TSRosWGetType_RosW);CHKERRQ(ierr); 1189e27a552bSJed Brown ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSRosWSetType_C","TSRosWSetType_RosW",TSRosWSetType_RosW);CHKERRQ(ierr); 119061692a83SJed Brown ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSRosWSetRecomputeJacobian_C","TSRosWSetRecomputeJacobian_RosW",TSRosWSetRecomputeJacobian_RosW);CHKERRQ(ierr); 1191e27a552bSJed Brown PetscFunctionReturn(0); 1192e27a552bSJed Brown } 1193e27a552bSJed Brown EXTERN_C_END 1194