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 1761692a83SJed Brown static const TSRosWType TSRosWDefault = TSROSW2P; 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 */ 26e27a552bSJed Brown PetscInt pinterp; /* Interpolation order */ 2761692a83SJed Brown PetscReal *A; /* Propagation table, strictly lower triangular */ 2861692a83SJed Brown PetscReal *Gamma; /* Stage table, lower triangular with nonzero diagonal */ 2961692a83SJed Brown PetscReal *b; /* Step completion table */ 3061692a83SJed Brown PetscReal *ASum; /* Row sum of A */ 3161692a83SJed Brown PetscReal *GammaSum; /* Row sum of Gamma, only needed for non-autonomous systems */ 3261692a83SJed Brown PetscReal *At; /* Propagation table in transformed variables */ 3361692a83SJed Brown PetscReal *bt; /* Step completion table in transformed variables */ 3461692a83SJed Brown PetscReal *GammaInv; /* Inverse of Gamma, used for transformed variables */ 35e27a552bSJed Brown }; 3661692a83SJed Brown typedef struct _RosWTableauLink *RosWTableauLink; 3761692a83SJed Brown struct _RosWTableauLink { 3861692a83SJed Brown struct _RosWTableau tab; 3961692a83SJed Brown RosWTableauLink next; 40e27a552bSJed Brown }; 4161692a83SJed Brown static RosWTableauLink RosWTableauList; 42e27a552bSJed Brown 43e27a552bSJed Brown typedef struct { 4461692a83SJed Brown RosWTableau tableau; 4561692a83SJed Brown Vec *Y; /* States computed during the step, used to complete the step */ 46e27a552bSJed Brown Vec Ydot; /* Work vector holding Ydot during residual evaluation */ 4761692a83SJed Brown Vec Ystage; /* Work vector for the state value at each stage */ 4861692a83SJed Brown Vec Zdot; /* Ydot = Zdot + shift*Y */ 4961692a83SJed Brown Vec Zstage; /* Y = Zstage + Y */ 50e27a552bSJed Brown PetscScalar *work; /* Scalar work */ 51e27a552bSJed Brown PetscReal shift; 52e27a552bSJed Brown PetscReal stage_time; 5361692a83SJed Brown PetscBool recompute_jacobian; /* Recompute the Jacobian at each stage, default is to freeze the Jacobian at the start of each step */ 54e27a552bSJed Brown } TS_RosW; 55e27a552bSJed Brown 56e27a552bSJed Brown #undef __FUNCT__ 57e27a552bSJed Brown #define __FUNCT__ "TSRosWRegisterAll" 58e27a552bSJed Brown /*@C 59e27a552bSJed Brown TSRosWRegisterAll - Registers all of the additive Runge-Kutta implicit-explicit methods in TSRosW 60e27a552bSJed Brown 61e27a552bSJed Brown Not Collective, but should be called by all processes which will need the schemes to be registered 62e27a552bSJed Brown 63e27a552bSJed Brown Level: advanced 64e27a552bSJed Brown 65e27a552bSJed Brown .keywords: TS, TSRosW, register, all 66e27a552bSJed Brown 67e27a552bSJed Brown .seealso: TSRosWRegisterDestroy() 68e27a552bSJed Brown @*/ 69e27a552bSJed Brown PetscErrorCode TSRosWRegisterAll(void) 70e27a552bSJed Brown { 71e27a552bSJed Brown PetscErrorCode ierr; 72e27a552bSJed Brown 73e27a552bSJed Brown PetscFunctionBegin; 74e27a552bSJed Brown if (TSRosWRegisterAllCalled) PetscFunctionReturn(0); 75e27a552bSJed Brown TSRosWRegisterAllCalled = PETSC_TRUE; 76e27a552bSJed Brown 77e27a552bSJed Brown { 7861692a83SJed Brown const PetscReal g = 1. + 1./PetscSqrtReal(2.0); 79e27a552bSJed Brown const PetscReal 8061692a83SJed Brown A[2][2] = {{0,0}, {1.,0}}, 8161692a83SJed Brown Gamma[2][2] = {{g,0}, {-2.*g,g}}, 8261692a83SJed Brown b[2] = {0.5,0.5}; 8361692a83SJed Brown ierr = TSRosWRegister(TSROSW2P,2,2,&A[0][0],&Gamma[0][0],b);CHKERRQ(ierr); 84e27a552bSJed Brown } 85e27a552bSJed Brown { 8661692a83SJed Brown const PetscReal g = 1. - 1./PetscSqrtReal(2.0); 87e27a552bSJed Brown const PetscReal 8861692a83SJed Brown A[2][2] = {{0,0}, {1.,0}}, 8961692a83SJed Brown Gamma[2][2] = {{g,0}, {-2.*g,g}}, 9061692a83SJed Brown b[2] = {0.5,0.5}; 9161692a83SJed Brown ierr = TSRosWRegister(TSROSW2M,2,2,&A[0][0],&Gamma[0][0],b);CHKERRQ(ierr); 92e27a552bSJed Brown } 93e27a552bSJed Brown PetscFunctionReturn(0); 94e27a552bSJed Brown } 95e27a552bSJed Brown 96e27a552bSJed Brown #undef __FUNCT__ 97e27a552bSJed Brown #define __FUNCT__ "TSRosWRegisterDestroy" 98e27a552bSJed Brown /*@C 99e27a552bSJed Brown TSRosWRegisterDestroy - Frees the list of schemes that were registered by TSRosWRegister(). 100e27a552bSJed Brown 101e27a552bSJed Brown Not Collective 102e27a552bSJed Brown 103e27a552bSJed Brown Level: advanced 104e27a552bSJed Brown 105e27a552bSJed Brown .keywords: TSRosW, register, destroy 106e27a552bSJed Brown .seealso: TSRosWRegister(), TSRosWRegisterAll(), TSRosWRegisterDynamic() 107e27a552bSJed Brown @*/ 108e27a552bSJed Brown PetscErrorCode TSRosWRegisterDestroy(void) 109e27a552bSJed Brown { 110e27a552bSJed Brown PetscErrorCode ierr; 11161692a83SJed Brown RosWTableauLink link; 112e27a552bSJed Brown 113e27a552bSJed Brown PetscFunctionBegin; 11461692a83SJed Brown while ((link = RosWTableauList)) { 11561692a83SJed Brown RosWTableau t = &link->tab; 11661692a83SJed Brown RosWTableauList = link->next; 11761692a83SJed Brown ierr = PetscFree5(t->A,t->Gamma,t->b,t->ASum,t->GammaSum);CHKERRQ(ierr); 11861692a83SJed Brown ierr = PetscFree3(t->At,t->bt,t->GammaInv);CHKERRQ(ierr); 119e27a552bSJed Brown ierr = PetscFree(t->name);CHKERRQ(ierr); 120e27a552bSJed Brown ierr = PetscFree(link);CHKERRQ(ierr); 121e27a552bSJed Brown } 122e27a552bSJed Brown TSRosWRegisterAllCalled = PETSC_FALSE; 123e27a552bSJed Brown PetscFunctionReturn(0); 124e27a552bSJed Brown } 125e27a552bSJed Brown 126e27a552bSJed Brown #undef __FUNCT__ 127e27a552bSJed Brown #define __FUNCT__ "TSRosWInitializePackage" 128e27a552bSJed Brown /*@C 129e27a552bSJed Brown TSRosWInitializePackage - This function initializes everything in the TSRosW package. It is called 130e27a552bSJed Brown from PetscDLLibraryRegister() when using dynamic libraries, and on the first call to TSCreate_RosW() 131e27a552bSJed Brown when using static libraries. 132e27a552bSJed Brown 133e27a552bSJed Brown Input Parameter: 134e27a552bSJed Brown path - The dynamic library path, or PETSC_NULL 135e27a552bSJed Brown 136e27a552bSJed Brown Level: developer 137e27a552bSJed Brown 138e27a552bSJed Brown .keywords: TS, TSRosW, initialize, package 139e27a552bSJed Brown .seealso: PetscInitialize() 140e27a552bSJed Brown @*/ 141e27a552bSJed Brown PetscErrorCode TSRosWInitializePackage(const char path[]) 142e27a552bSJed Brown { 143e27a552bSJed Brown PetscErrorCode ierr; 144e27a552bSJed Brown 145e27a552bSJed Brown PetscFunctionBegin; 146e27a552bSJed Brown if (TSRosWPackageInitialized) PetscFunctionReturn(0); 147e27a552bSJed Brown TSRosWPackageInitialized = PETSC_TRUE; 148e27a552bSJed Brown ierr = TSRosWRegisterAll();CHKERRQ(ierr); 149e27a552bSJed Brown ierr = PetscRegisterFinalize(TSRosWFinalizePackage);CHKERRQ(ierr); 150e27a552bSJed Brown PetscFunctionReturn(0); 151e27a552bSJed Brown } 152e27a552bSJed Brown 153e27a552bSJed Brown #undef __FUNCT__ 154e27a552bSJed Brown #define __FUNCT__ "TSRosWFinalizePackage" 155e27a552bSJed Brown /*@C 156e27a552bSJed Brown TSRosWFinalizePackage - This function destroys everything in the TSRosW package. It is 157e27a552bSJed Brown called from PetscFinalize(). 158e27a552bSJed Brown 159e27a552bSJed Brown Level: developer 160e27a552bSJed Brown 161e27a552bSJed Brown .keywords: Petsc, destroy, package 162e27a552bSJed Brown .seealso: PetscFinalize() 163e27a552bSJed Brown @*/ 164e27a552bSJed Brown PetscErrorCode TSRosWFinalizePackage(void) 165e27a552bSJed Brown { 166e27a552bSJed Brown PetscErrorCode ierr; 167e27a552bSJed Brown 168e27a552bSJed Brown PetscFunctionBegin; 169e27a552bSJed Brown TSRosWPackageInitialized = PETSC_FALSE; 170e27a552bSJed Brown ierr = TSRosWRegisterDestroy();CHKERRQ(ierr); 171e27a552bSJed Brown PetscFunctionReturn(0); 172e27a552bSJed Brown } 173e27a552bSJed Brown 174e27a552bSJed Brown #undef __FUNCT__ 175e27a552bSJed Brown #define __FUNCT__ "TSRosWRegister" 176e27a552bSJed Brown /*@C 17761692a83SJed Brown TSRosWRegister - register a Rosenbrock W scheme by providing the entries in the Butcher tableau and optionally embedded approximations and interpolation 178e27a552bSJed Brown 179e27a552bSJed Brown Not Collective, but the same schemes should be registered on all processes on which they will be used 180e27a552bSJed Brown 181e27a552bSJed Brown Input Parameters: 182e27a552bSJed Brown + name - identifier for method 183e27a552bSJed Brown . order - approximation order of method 184e27a552bSJed Brown . s - number of stages, this is the dimension of the matrices below 18561692a83SJed Brown . A - Table of propagated stage coefficients (dimension s*s, row-major), strictly lower triangular 18661692a83SJed Brown . Gamma - Table of coefficients in implicit stage equations (dimension s*s, row-major), lower triangular with nonzero diagonal 18761692a83SJed Brown - b - Step completion table (dimension s) 188e27a552bSJed Brown 189e27a552bSJed Brown Notes: 19061692a83SJed Brown Several Rosenbrock W methods are provided, this function is only needed to create new methods. 191e27a552bSJed Brown 192e27a552bSJed Brown Level: advanced 193e27a552bSJed Brown 194e27a552bSJed Brown .keywords: TS, register 195e27a552bSJed Brown 196e27a552bSJed Brown .seealso: TSRosW 197e27a552bSJed Brown @*/ 198e27a552bSJed Brown PetscErrorCode TSRosWRegister(const TSRosWType name,PetscInt order,PetscInt s, 19961692a83SJed Brown const PetscReal A[],const PetscReal Gamma[],const PetscReal b[]) 200e27a552bSJed Brown { 201e27a552bSJed Brown PetscErrorCode ierr; 20261692a83SJed Brown RosWTableauLink link; 20361692a83SJed Brown RosWTableau t; 20461692a83SJed Brown PetscInt i,j,k; 20561692a83SJed Brown PetscScalar *GammaInv; 206e27a552bSJed Brown 207e27a552bSJed Brown PetscFunctionBegin; 208e27a552bSJed Brown ierr = PetscMalloc(sizeof(*link),&link);CHKERRQ(ierr); 209e27a552bSJed Brown ierr = PetscMemzero(link,sizeof(*link));CHKERRQ(ierr); 210e27a552bSJed Brown t = &link->tab; 211e27a552bSJed Brown ierr = PetscStrallocpy(name,&t->name);CHKERRQ(ierr); 212e27a552bSJed Brown t->order = order; 213e27a552bSJed Brown t->s = s; 21461692a83SJed 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); 21561692a83SJed Brown ierr = PetscMalloc3(s*s,PetscReal,&t->At,s,PetscReal,&t->bt,s*s,PetscReal,&t->GammaInv);CHKERRQ(ierr); 216e27a552bSJed Brown ierr = PetscMemcpy(t->A,A,s*s*sizeof(A[0]));CHKERRQ(ierr); 21761692a83SJed Brown ierr = PetscMemcpy(t->Gamma,Gamma,s*s*sizeof(Gamma[0]));CHKERRQ(ierr); 21861692a83SJed Brown ierr = PetscMemcpy(t->b,b,s*sizeof(b[0]));CHKERRQ(ierr); 21961692a83SJed Brown for (i=0; i<s; i++) { 22061692a83SJed Brown t->ASum[i] = 0; 22161692a83SJed Brown t->GammaSum[i] = 0; 22261692a83SJed Brown for (j=0; j<s; j++) { 22361692a83SJed Brown t->ASum[i] += A[i*s+j]; 22461692a83SJed Brown t->GammaSum[i] = Gamma[i*s+j]; 22561692a83SJed Brown } 22661692a83SJed Brown } 22761692a83SJed Brown ierr = PetscMalloc(s*s*sizeof(PetscScalar),&GammaInv);CHKERRQ(ierr); /* Need to use Scalar for inverse, then convert back to Real */ 22861692a83SJed Brown for (i=0; i<s*s; i++) GammaInv[i] = Gamma[i]; 22961692a83SJed Brown switch (s) { 23061692a83SJed Brown case 1: GammaInv[0] = 1./GammaInv[0]; break; 23161692a83SJed Brown case 2: ierr = Kernel_A_gets_inverse_A_2(GammaInv,0);CHKERRQ(ierr); break; 23261692a83SJed Brown case 3: ierr = Kernel_A_gets_inverse_A_3(GammaInv,0);CHKERRQ(ierr); break; 23361692a83SJed Brown case 4: ierr = Kernel_A_gets_inverse_A_4(GammaInv,0);CHKERRQ(ierr); break; 23461692a83SJed Brown case 5: { 23561692a83SJed Brown PetscInt ipvt5[5]; 23661692a83SJed Brown MatScalar work5[5*5]; 23761692a83SJed Brown ierr = Kernel_A_gets_inverse_A_5(GammaInv,ipvt5,work5,0);CHKERRQ(ierr); break; 23861692a83SJed Brown } 23961692a83SJed Brown case 6: ierr = Kernel_A_gets_inverse_A_6(GammaInv,0);CHKERRQ(ierr); break; 24061692a83SJed Brown case 7: ierr = Kernel_A_gets_inverse_A_7(GammaInv,0);CHKERRQ(ierr); break; 24161692a83SJed Brown default: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented for %D stages",s); 24261692a83SJed Brown } 24361692a83SJed Brown for (i=0; i<s*s; i++) t->GammaInv[i] = PetscRealPart(GammaInv[i]); 24461692a83SJed Brown ierr = PetscFree(GammaInv);CHKERRQ(ierr); 24561692a83SJed Brown for (i=0; i<s; i++) { 24661692a83SJed Brown for (j=0; j<s; j++) { 24761692a83SJed Brown t->At[i*s+j] = 0; 24861692a83SJed Brown for (k=0; k<s; k++) { 24961692a83SJed Brown t->At[i*s+j] += t->A[i*s+k] * t->GammaInv[k*s+j]; 25061692a83SJed Brown } 25161692a83SJed Brown } 25261692a83SJed Brown t->bt[i] = 0; 25361692a83SJed Brown for (j=0; j<s; j++) { 25461692a83SJed Brown t->bt[i] += t->b[j] * t->GammaInv[j*s+i]; 25561692a83SJed Brown } 25661692a83SJed Brown } 25761692a83SJed Brown link->next = RosWTableauList; 25861692a83SJed Brown RosWTableauList = link; 259e27a552bSJed Brown PetscFunctionReturn(0); 260e27a552bSJed Brown } 261e27a552bSJed Brown 262e27a552bSJed Brown #undef __FUNCT__ 263e27a552bSJed Brown #define __FUNCT__ "TSStep_RosW" 264e27a552bSJed Brown static PetscErrorCode TSStep_RosW(TS ts) 265e27a552bSJed Brown { 26661692a83SJed Brown TS_RosW *ros = (TS_RosW*)ts->data; 26761692a83SJed Brown RosWTableau tab = ros->tableau; 268e27a552bSJed Brown const PetscInt s = tab->s; 26961692a83SJed Brown const PetscReal *At = tab->At,*Gamma = tab->Gamma,*bt = tab->bt,*ASum = tab->ASum,*GammaInv = tab->GammaInv; 27061692a83SJed Brown PetscScalar *w = ros->work; 27161692a83SJed Brown Vec *Y = ros->Y,Zdot = ros->Zdot,Zstage = ros->Zstage; 272e27a552bSJed Brown SNES snes; 273e27a552bSJed Brown PetscInt i,j,its,lits; 274cdbf8f93SLisandro Dalcin PetscReal next_time_step; 275e27a552bSJed Brown PetscReal h,t; 276e27a552bSJed Brown PetscErrorCode ierr; 277e27a552bSJed Brown 278e27a552bSJed Brown PetscFunctionBegin; 279e27a552bSJed Brown ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 280cdbf8f93SLisandro Dalcin next_time_step = ts->time_step; 281cdbf8f93SLisandro Dalcin h = ts->time_step; 282e27a552bSJed Brown t = ts->ptime; 283e27a552bSJed Brown 284e27a552bSJed Brown for (i=0; i<s; i++) { 28561692a83SJed Brown ros->stage_time = t + h*ASum[i]; 28661692a83SJed Brown ros->shift = 1./(h*Gamma[i*s+i]); 28761692a83SJed Brown 28861692a83SJed Brown ierr = VecCopy(ts->vec_sol,Zstage);CHKERRQ(ierr); 28961692a83SJed Brown ierr = VecMAXPY(Zstage,i,&At[i*s+0],Y);CHKERRQ(ierr); 29061692a83SJed Brown 29161692a83SJed Brown for (j=0; j<i; j++) w[j] = 1./h * GammaInv[i*s+j]; 29261692a83SJed Brown ierr = VecZeroEntries(Zdot);CHKERRQ(ierr); 29361692a83SJed Brown ierr = VecMAXPY(Zdot,i,w,Y);CHKERRQ(ierr); 29461692a83SJed Brown 295e27a552bSJed Brown /* Initial guess taken from last stage */ 29661692a83SJed Brown ierr = VecZeroEntries(Y[i]);CHKERRQ(ierr); 29761692a83SJed Brown 29861692a83SJed Brown if (!ros->recompute_jacobian && !i) { 29961692a83SJed Brown ierr = SNESSetLagJacobian(snes,-2);CHKERRQ(ierr); /* Recompute the Jacobian on this solve, but not again */ 30061692a83SJed Brown } 30161692a83SJed Brown 30261692a83SJed Brown ierr = SNESSolve(snes,PETSC_NULL,Y[i]);CHKERRQ(ierr); 303e27a552bSJed Brown ierr = SNESGetIterationNumber(snes,&its);CHKERRQ(ierr); 304e27a552bSJed Brown ierr = SNESGetLinearSolveIterations(snes,&lits);CHKERRQ(ierr); 305e27a552bSJed Brown ts->nonlinear_its += its; ts->linear_its += lits; 306e27a552bSJed Brown } 30761692a83SJed Brown ierr = VecMAXPY(ts->vec_sol,s,bt,Y);CHKERRQ(ierr); 308e27a552bSJed Brown 309e27a552bSJed Brown ts->ptime += ts->time_step; 310cdbf8f93SLisandro Dalcin ts->time_step = next_time_step; 311e27a552bSJed Brown ts->steps++; 312e27a552bSJed Brown PetscFunctionReturn(0); 313e27a552bSJed Brown } 314e27a552bSJed Brown 315e27a552bSJed Brown #undef __FUNCT__ 316e27a552bSJed Brown #define __FUNCT__ "TSInterpolate_RosW" 317e27a552bSJed Brown static PetscErrorCode TSInterpolate_RosW(TS ts,PetscReal itime,Vec X) 318e27a552bSJed Brown { 31961692a83SJed Brown TS_RosW *ros = (TS_RosW*)ts->data; 320e27a552bSJed Brown 321e27a552bSJed Brown PetscFunctionBegin; 32261692a83SJed Brown SETERRQ1(((PetscObject)ts)->comm,PETSC_ERR_SUP,"TSRosW %s does not have an interpolation formula",ros->tableau->name); 323e27a552bSJed Brown PetscFunctionReturn(0); 324e27a552bSJed Brown } 325e27a552bSJed Brown 326e27a552bSJed Brown /*------------------------------------------------------------*/ 327e27a552bSJed Brown #undef __FUNCT__ 328e27a552bSJed Brown #define __FUNCT__ "TSReset_RosW" 329e27a552bSJed Brown static PetscErrorCode TSReset_RosW(TS ts) 330e27a552bSJed Brown { 33161692a83SJed Brown TS_RosW *ros = (TS_RosW*)ts->data; 332e27a552bSJed Brown PetscInt s; 333e27a552bSJed Brown PetscErrorCode ierr; 334e27a552bSJed Brown 335e27a552bSJed Brown PetscFunctionBegin; 33661692a83SJed Brown if (!ros->tableau) PetscFunctionReturn(0); 33761692a83SJed Brown s = ros->tableau->s; 33861692a83SJed Brown ierr = VecDestroyVecs(s,&ros->Y);CHKERRQ(ierr); 33961692a83SJed Brown ierr = VecDestroy(&ros->Ydot);CHKERRQ(ierr); 34061692a83SJed Brown ierr = VecDestroy(&ros->Ystage);CHKERRQ(ierr); 34161692a83SJed Brown ierr = VecDestroy(&ros->Zdot);CHKERRQ(ierr); 34261692a83SJed Brown ierr = VecDestroy(&ros->Zstage);CHKERRQ(ierr); 34361692a83SJed Brown ierr = PetscFree(ros->work);CHKERRQ(ierr); 344e27a552bSJed Brown PetscFunctionReturn(0); 345e27a552bSJed Brown } 346e27a552bSJed Brown 347e27a552bSJed Brown #undef __FUNCT__ 348e27a552bSJed Brown #define __FUNCT__ "TSDestroy_RosW" 349e27a552bSJed Brown static PetscErrorCode TSDestroy_RosW(TS ts) 350e27a552bSJed Brown { 351e27a552bSJed Brown PetscErrorCode ierr; 352e27a552bSJed Brown 353e27a552bSJed Brown PetscFunctionBegin; 354e27a552bSJed Brown ierr = TSReset_RosW(ts);CHKERRQ(ierr); 355e27a552bSJed Brown ierr = PetscFree(ts->data);CHKERRQ(ierr); 356e27a552bSJed Brown ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSRosWGetType_C","",PETSC_NULL);CHKERRQ(ierr); 357e27a552bSJed Brown ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSRosWSetType_C","",PETSC_NULL);CHKERRQ(ierr); 35861692a83SJed Brown ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSRosWSetRecomputeJacobian_C","",PETSC_NULL);CHKERRQ(ierr); 359e27a552bSJed Brown PetscFunctionReturn(0); 360e27a552bSJed Brown } 361e27a552bSJed Brown 362e27a552bSJed Brown /* 363e27a552bSJed Brown This defines the nonlinear equation that is to be solved with SNES 364e27a552bSJed Brown G(U) = F[t0+Theta*dt, U, (U-U0)*shift] = 0 365e27a552bSJed Brown */ 366e27a552bSJed Brown #undef __FUNCT__ 367e27a552bSJed Brown #define __FUNCT__ "SNESTSFormFunction_RosW" 368e27a552bSJed Brown static PetscErrorCode SNESTSFormFunction_RosW(SNES snes,Vec X,Vec F,TS ts) 369e27a552bSJed Brown { 37061692a83SJed Brown TS_RosW *ros = (TS_RosW*)ts->data; 371e27a552bSJed Brown PetscErrorCode ierr; 372e27a552bSJed Brown 373e27a552bSJed Brown PetscFunctionBegin; 37461692a83SJed Brown ierr = VecWAXPY(ros->Ydot,ros->shift,X,ros->Zdot);CHKERRQ(ierr); /* Ydot = shift*X + Zdot */ 37561692a83SJed Brown ierr = VecWAXPY(ros->Ystage,1.0,X,ros->Zstage);CHKERRQ(ierr); /* Ystage = X + Zstage */ 37661692a83SJed Brown ierr = TSComputeIFunction(ts,ros->stage_time,ros->Ystage,ros->Ydot,F,PETSC_FALSE);CHKERRQ(ierr); 377e27a552bSJed Brown PetscFunctionReturn(0); 378e27a552bSJed Brown } 379e27a552bSJed Brown 380e27a552bSJed Brown #undef __FUNCT__ 381e27a552bSJed Brown #define __FUNCT__ "SNESTSFormJacobian_RosW" 382e27a552bSJed Brown static PetscErrorCode SNESTSFormJacobian_RosW(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *str,TS ts) 383e27a552bSJed Brown { 38461692a83SJed Brown TS_RosW *ros = (TS_RosW*)ts->data; 385e27a552bSJed Brown PetscErrorCode ierr; 386e27a552bSJed Brown 387e27a552bSJed Brown PetscFunctionBegin; 38861692a83SJed Brown /* ros->Ydot and ros->Ystage have already been computed in SNESTSFormFunction_RosW (SNES guarantees this) */ 38961692a83SJed Brown ierr = TSComputeIJacobian(ts,ros->stage_time,ros->Ystage,ros->Ydot,ros->shift,A,B,str,PETSC_TRUE);CHKERRQ(ierr); 390e27a552bSJed Brown PetscFunctionReturn(0); 391e27a552bSJed Brown } 392e27a552bSJed Brown 393e27a552bSJed Brown #undef __FUNCT__ 394e27a552bSJed Brown #define __FUNCT__ "TSSetUp_RosW" 395e27a552bSJed Brown static PetscErrorCode TSSetUp_RosW(TS ts) 396e27a552bSJed Brown { 39761692a83SJed Brown TS_RosW *ros = (TS_RosW*)ts->data; 39861692a83SJed Brown RosWTableau tab = ros->tableau; 399e27a552bSJed Brown PetscInt s = tab->s; 400e27a552bSJed Brown PetscErrorCode ierr; 401e27a552bSJed Brown 402e27a552bSJed Brown PetscFunctionBegin; 40361692a83SJed Brown if (!ros->tableau) { 404e27a552bSJed Brown ierr = TSRosWSetType(ts,TSRosWDefault);CHKERRQ(ierr); 405e27a552bSJed Brown } 40661692a83SJed Brown ierr = VecDuplicateVecs(ts->vec_sol,s,&ros->Y);CHKERRQ(ierr); 40761692a83SJed Brown ierr = VecDuplicate(ts->vec_sol,&ros->Ydot);CHKERRQ(ierr); 40861692a83SJed Brown ierr = VecDuplicate(ts->vec_sol,&ros->Ystage);CHKERRQ(ierr); 40961692a83SJed Brown ierr = VecDuplicate(ts->vec_sol,&ros->Zdot);CHKERRQ(ierr); 41061692a83SJed Brown ierr = VecDuplicate(ts->vec_sol,&ros->Zstage);CHKERRQ(ierr); 41161692a83SJed Brown ierr = PetscMalloc(s*sizeof(ros->work[0]),&ros->work);CHKERRQ(ierr); 412e27a552bSJed Brown PetscFunctionReturn(0); 413e27a552bSJed Brown } 414e27a552bSJed Brown /*------------------------------------------------------------*/ 415e27a552bSJed Brown 416e27a552bSJed Brown #undef __FUNCT__ 417e27a552bSJed Brown #define __FUNCT__ "TSSetFromOptions_RosW" 418e27a552bSJed Brown static PetscErrorCode TSSetFromOptions_RosW(TS ts) 419e27a552bSJed Brown { 42061692a83SJed Brown TS_RosW *ros = (TS_RosW*)ts->data; 421e27a552bSJed Brown PetscErrorCode ierr; 42261692a83SJed Brown char rostype[256]; 423e27a552bSJed Brown 424e27a552bSJed Brown PetscFunctionBegin; 425e27a552bSJed Brown ierr = PetscOptionsHead("RosW ODE solver options");CHKERRQ(ierr); 426e27a552bSJed Brown { 42761692a83SJed Brown RosWTableauLink link; 428e27a552bSJed Brown PetscInt count,choice; 429e27a552bSJed Brown PetscBool flg; 430e27a552bSJed Brown const char **namelist; 43161692a83SJed Brown SNES snes; 43261692a83SJed Brown 43361692a83SJed Brown ierr = PetscStrncpy(rostype,TSRosWDefault,sizeof rostype);CHKERRQ(ierr); 43461692a83SJed Brown for (link=RosWTableauList,count=0; link; link=link->next,count++) ; 435e27a552bSJed Brown ierr = PetscMalloc(count*sizeof(char*),&namelist);CHKERRQ(ierr); 43661692a83SJed Brown for (link=RosWTableauList,count=0; link; link=link->next,count++) namelist[count] = link->tab.name; 43761692a83SJed Brown ierr = PetscOptionsEList("-ts_rosw_type","Family of Rosenbrock-W method","TSRosWSetType",(const char*const*)namelist,count,rostype,&choice,&flg);CHKERRQ(ierr); 43861692a83SJed Brown ierr = TSRosWSetType(ts,flg ? namelist[choice] : rostype);CHKERRQ(ierr); 439e27a552bSJed Brown ierr = PetscFree(namelist);CHKERRQ(ierr); 44061692a83SJed Brown 44161692a83SJed Brown ierr = PetscOptionsBool("-ts_rosw_recompute_jacobian","Recompute the Jacobian at each stage","TSRosWSetRecomputeJacobian",ros->recompute_jacobian,&ros->recompute_jacobian,PETSC_NULL);CHKERRQ(ierr); 44261692a83SJed Brown 44361692a83SJed Brown /* Rosenbrock methods are linearly implicit, so set that unless the user has specifically asked for something else */ 44461692a83SJed Brown ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 44561692a83SJed Brown if (!((PetscObject)snes)->type_name) { 44661692a83SJed Brown ierr = SNESSetType(snes,SNESKSPONLY);CHKERRQ(ierr); 44761692a83SJed Brown } 44861692a83SJed Brown ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); 449e27a552bSJed Brown } 450e27a552bSJed Brown ierr = PetscOptionsTail();CHKERRQ(ierr); 451e27a552bSJed Brown PetscFunctionReturn(0); 452e27a552bSJed Brown } 453e27a552bSJed Brown 454e27a552bSJed Brown #undef __FUNCT__ 455e27a552bSJed Brown #define __FUNCT__ "PetscFormatRealArray" 456e27a552bSJed Brown static PetscErrorCode PetscFormatRealArray(char buf[],size_t len,const char *fmt,PetscInt n,const PetscReal x[]) 457e27a552bSJed Brown { 458e27a552bSJed Brown PetscErrorCode ierr; 459*e408995aSJed Brown PetscInt i; 460*e408995aSJed Brown size_t left,count; 461e27a552bSJed Brown char *p; 462e27a552bSJed Brown 463e27a552bSJed Brown PetscFunctionBegin; 464*e408995aSJed Brown for (i=0,p=buf,left=len; i<n; i++) { 465*e408995aSJed Brown ierr = PetscSNPrintfCount(p,left,fmt,&count,x[i]);CHKERRQ(ierr); 466e27a552bSJed Brown if (count >= left) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Insufficient space in buffer"); 467e27a552bSJed Brown left -= count; 468e27a552bSJed Brown p += count; 469e27a552bSJed Brown *p++ = ' '; 470e27a552bSJed Brown } 471e27a552bSJed Brown p[i ? 0 : -1] = 0; 472e27a552bSJed Brown PetscFunctionReturn(0); 473e27a552bSJed Brown } 474e27a552bSJed Brown 475e27a552bSJed Brown #undef __FUNCT__ 476e27a552bSJed Brown #define __FUNCT__ "TSView_RosW" 477e27a552bSJed Brown static PetscErrorCode TSView_RosW(TS ts,PetscViewer viewer) 478e27a552bSJed Brown { 47961692a83SJed Brown TS_RosW *ros = (TS_RosW*)ts->data; 48061692a83SJed Brown RosWTableau tab = ros->tableau; 481e27a552bSJed Brown PetscBool iascii; 482e27a552bSJed Brown PetscErrorCode ierr; 483e27a552bSJed Brown 484e27a552bSJed Brown PetscFunctionBegin; 485e27a552bSJed Brown ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 486e27a552bSJed Brown if (iascii) { 48761692a83SJed Brown const TSRosWType rostype; 488*e408995aSJed Brown PetscInt i; 489*e408995aSJed Brown PetscReal abscissa[512]; 490e27a552bSJed Brown char buf[512]; 49161692a83SJed Brown ierr = TSRosWGetType(ts,&rostype);CHKERRQ(ierr); 49261692a83SJed Brown ierr = PetscViewerASCIIPrintf(viewer," Rosenbrock-W %s\n",rostype);CHKERRQ(ierr); 493*e408995aSJed Brown ierr = PetscFormatRealArray(buf,sizeof buf,"% 8.6f",tab->s,tab->ASum);CHKERRQ(ierr); 49461692a83SJed Brown ierr = PetscViewerASCIIPrintf(viewer," Abscissa of A = %s\n",buf);CHKERRQ(ierr); 495*e408995aSJed Brown for (i=0; i<tab->s; i++) abscissa[i] = tab->ASum[i] + tab->Gamma[i]; 496*e408995aSJed Brown ierr = PetscFormatRealArray(buf,sizeof buf,"% 8.6f",tab->s,abscissa);CHKERRQ(ierr); 497*e408995aSJed Brown ierr = PetscViewerASCIIPrintf(viewer," Abscissa of A+Gamma = %s\n",buf);CHKERRQ(ierr); 498e27a552bSJed Brown } 499e27a552bSJed Brown ierr = SNESView(ts->snes,viewer);CHKERRQ(ierr); 500e27a552bSJed Brown PetscFunctionReturn(0); 501e27a552bSJed Brown } 502e27a552bSJed Brown 503e27a552bSJed Brown #undef __FUNCT__ 504e27a552bSJed Brown #define __FUNCT__ "TSRosWSetType" 505e27a552bSJed Brown /*@C 50661692a83SJed Brown TSRosWSetType - Set the type of Rosenbrock-W scheme 507e27a552bSJed Brown 508e27a552bSJed Brown Logically collective 509e27a552bSJed Brown 510e27a552bSJed Brown Input Parameter: 511e27a552bSJed Brown + ts - timestepping context 51261692a83SJed Brown - rostype - type of Rosenbrock-W scheme 513e27a552bSJed Brown 514e27a552bSJed Brown Level: intermediate 515e27a552bSJed Brown 516e27a552bSJed Brown .seealso: TSRosWGetType() 517e27a552bSJed Brown @*/ 51861692a83SJed Brown PetscErrorCode TSRosWSetType(TS ts,const TSRosWType rostype) 519e27a552bSJed Brown { 520e27a552bSJed Brown PetscErrorCode ierr; 521e27a552bSJed Brown 522e27a552bSJed Brown PetscFunctionBegin; 523e27a552bSJed Brown PetscValidHeaderSpecific(ts,TS_CLASSID,1); 52461692a83SJed Brown ierr = PetscTryMethod(ts,"TSRosWSetType_C",(TS,const TSRosWType),(ts,rostype));CHKERRQ(ierr); 525e27a552bSJed Brown PetscFunctionReturn(0); 526e27a552bSJed Brown } 527e27a552bSJed Brown 528e27a552bSJed Brown #undef __FUNCT__ 529e27a552bSJed Brown #define __FUNCT__ "TSRosWGetType" 530e27a552bSJed Brown /*@C 53161692a83SJed Brown TSRosWGetType - Get the type of Rosenbrock-W scheme 532e27a552bSJed Brown 533e27a552bSJed Brown Logically collective 534e27a552bSJed Brown 535e27a552bSJed Brown Input Parameter: 536e27a552bSJed Brown . ts - timestepping context 537e27a552bSJed Brown 538e27a552bSJed Brown Output Parameter: 53961692a83SJed Brown . rostype - type of Rosenbrock-W scheme 540e27a552bSJed Brown 541e27a552bSJed Brown Level: intermediate 542e27a552bSJed Brown 543e27a552bSJed Brown .seealso: TSRosWGetType() 544e27a552bSJed Brown @*/ 54561692a83SJed Brown PetscErrorCode TSRosWGetType(TS ts,const TSRosWType *rostype) 546e27a552bSJed Brown { 547e27a552bSJed Brown PetscErrorCode ierr; 548e27a552bSJed Brown 549e27a552bSJed Brown PetscFunctionBegin; 550e27a552bSJed Brown PetscValidHeaderSpecific(ts,TS_CLASSID,1); 55161692a83SJed Brown ierr = PetscUseMethod(ts,"TSRosWGetType_C",(TS,const TSRosWType*),(ts,rostype));CHKERRQ(ierr); 552e27a552bSJed Brown PetscFunctionReturn(0); 553e27a552bSJed Brown } 554e27a552bSJed Brown 555e27a552bSJed Brown #undef __FUNCT__ 55661692a83SJed Brown #define __FUNCT__ "TSRosWSetRecomputeJacobian" 557e27a552bSJed Brown /*@C 55861692a83SJed Brown TSRosWSetRecomputeJacobian - Set whether to recompute the Jacobian at each stage. The default is to update the Jacobian once per step. 559e27a552bSJed Brown 560e27a552bSJed Brown Logically collective 561e27a552bSJed Brown 562e27a552bSJed Brown Input Parameter: 563e27a552bSJed Brown + ts - timestepping context 56461692a83SJed Brown - flg - PETSC_TRUE to recompute the Jacobian at each stage 565e27a552bSJed Brown 566e27a552bSJed Brown Level: intermediate 567e27a552bSJed Brown 568e27a552bSJed Brown .seealso: TSRosWGetType() 569e27a552bSJed Brown @*/ 57061692a83SJed Brown PetscErrorCode TSRosWSetRecomputeJacobian(TS ts,PetscBool flg) 571e27a552bSJed Brown { 572e27a552bSJed Brown PetscErrorCode ierr; 573e27a552bSJed Brown 574e27a552bSJed Brown PetscFunctionBegin; 575e27a552bSJed Brown PetscValidHeaderSpecific(ts,TS_CLASSID,1); 57661692a83SJed Brown ierr = PetscTryMethod(ts,"TSRosWSetRecomputeJacobian_C",(TS,PetscBool),(ts,flg));CHKERRQ(ierr); 577e27a552bSJed Brown PetscFunctionReturn(0); 578e27a552bSJed Brown } 579e27a552bSJed Brown 580e27a552bSJed Brown EXTERN_C_BEGIN 581e27a552bSJed Brown #undef __FUNCT__ 582e27a552bSJed Brown #define __FUNCT__ "TSRosWGetType_RosW" 58361692a83SJed Brown PetscErrorCode TSRosWGetType_RosW(TS ts,const TSRosWType *rostype) 584e27a552bSJed Brown { 58561692a83SJed Brown TS_RosW *ros = (TS_RosW*)ts->data; 586e27a552bSJed Brown PetscErrorCode ierr; 587e27a552bSJed Brown 588e27a552bSJed Brown PetscFunctionBegin; 58961692a83SJed Brown if (!ros->tableau) {ierr = TSRosWSetType(ts,TSRosWDefault);CHKERRQ(ierr);} 59061692a83SJed Brown *rostype = ros->tableau->name; 591e27a552bSJed Brown PetscFunctionReturn(0); 592e27a552bSJed Brown } 593e27a552bSJed Brown #undef __FUNCT__ 594e27a552bSJed Brown #define __FUNCT__ "TSRosWSetType_RosW" 59561692a83SJed Brown PetscErrorCode TSRosWSetType_RosW(TS ts,const TSRosWType rostype) 596e27a552bSJed Brown { 59761692a83SJed Brown TS_RosW *ros = (TS_RosW*)ts->data; 598e27a552bSJed Brown PetscErrorCode ierr; 599e27a552bSJed Brown PetscBool match; 60061692a83SJed Brown RosWTableauLink link; 601e27a552bSJed Brown 602e27a552bSJed Brown PetscFunctionBegin; 60361692a83SJed Brown if (ros->tableau) { 60461692a83SJed Brown ierr = PetscStrcmp(ros->tableau->name,rostype,&match);CHKERRQ(ierr); 605e27a552bSJed Brown if (match) PetscFunctionReturn(0); 606e27a552bSJed Brown } 60761692a83SJed Brown for (link = RosWTableauList; link; link=link->next) { 60861692a83SJed Brown ierr = PetscStrcmp(link->tab.name,rostype,&match);CHKERRQ(ierr); 609e27a552bSJed Brown if (match) { 610e27a552bSJed Brown ierr = TSReset_RosW(ts);CHKERRQ(ierr); 61161692a83SJed Brown ros->tableau = &link->tab; 612e27a552bSJed Brown PetscFunctionReturn(0); 613e27a552bSJed Brown } 614e27a552bSJed Brown } 61561692a83SJed Brown SETERRQ1(((PetscObject)ts)->comm,PETSC_ERR_ARG_UNKNOWN_TYPE,"Could not find '%s'",rostype); 616e27a552bSJed Brown PetscFunctionReturn(0); 617e27a552bSJed Brown } 61861692a83SJed Brown 619e27a552bSJed Brown #undef __FUNCT__ 62061692a83SJed Brown #define __FUNCT__ "TSRosWSetRecomputeJacobian_RosW" 62161692a83SJed Brown PetscErrorCode TSRosWSetRecomputeJacobian_RosW(TS ts,PetscBool flg) 622e27a552bSJed Brown { 62361692a83SJed Brown TS_RosW *ros = (TS_RosW*)ts->data; 624e27a552bSJed Brown 625e27a552bSJed Brown PetscFunctionBegin; 62661692a83SJed Brown ros->recompute_jacobian = flg; 627e27a552bSJed Brown PetscFunctionReturn(0); 628e27a552bSJed Brown } 629e27a552bSJed Brown EXTERN_C_END 630e27a552bSJed Brown 631e27a552bSJed Brown /* ------------------------------------------------------------ */ 632e27a552bSJed Brown /*MC 633e27a552bSJed Brown TSRosW - ODE solver using Rosenbrock-W schemes 634e27a552bSJed Brown 635e27a552bSJed Brown These methods are intended for problems with well-separated time scales, especially when a slow scale is strongly 636e27a552bSJed Brown nonlinear such that it is expensive to solve with a fully implicit method. The user should provide the stiff part 637e27a552bSJed Brown of the equation using TSSetIFunction() and the non-stiff part with TSSetRHSFunction(). 638e27a552bSJed Brown 639e27a552bSJed Brown Notes: 64061692a83SJed Brown This method currently only works with autonomous ODE and DAE. 64161692a83SJed Brown 64261692a83SJed Brown Developer notes: 64361692a83SJed Brown Rosenbrock-W methods are typically specified for autonomous ODE 64461692a83SJed Brown 64561692a83SJed Brown $ xdot = f(x) 64661692a83SJed Brown 64761692a83SJed Brown by the stage equations 64861692a83SJed Brown 64961692a83SJed Brown $ k_i = h f(x_0 + sum_j alpha_ij k_j) + h J sum_j gamma_ij k_j 65061692a83SJed Brown 65161692a83SJed Brown and step completion formula 65261692a83SJed Brown 65361692a83SJed Brown $ x_1 = x_0 + sum_j b_j k_j 65461692a83SJed Brown 65561692a83SJed Brown with step size h and coefficients alpha_ij, gamma_ij, and b_i. Implementing the method in this form would require f(x) 65661692a83SJed Brown and the Jacobian J to be available, in addition to the shifted matrix I - h gamma_ii J. Following Hairer and Wanner, 65761692a83SJed Brown we define new variables for the stage equations 65861692a83SJed Brown 65961692a83SJed Brown $ y_i = gamma_ij k_j 66061692a83SJed Brown 66161692a83SJed Brown The k_j can be recovered because Gamma is invertible. Let C be the lower triangular part of Gamma^{-1} and define 66261692a83SJed Brown 66361692a83SJed Brown $ A = Alpha Gamma^{-1}, bt^T = b^T Gamma^{-i} 66461692a83SJed Brown 66561692a83SJed Brown to rewrite the method as 66661692a83SJed Brown 66761692a83SJed 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 66861692a83SJed Brown $ x_1 = x_0 + sum_j bt_j y_j 66961692a83SJed Brown 67061692a83SJed Brown where we have introduced the mass matrix M. Continue by defining 67161692a83SJed Brown 67261692a83SJed Brown $ ydot_i = 1/(h gamma_ii) y_i - sum_j (c_ij/h) y_j 67361692a83SJed Brown 67461692a83SJed Brown or, more compactly in tensor notation 67561692a83SJed Brown 67661692a83SJed Brown $ Ydot = 1/h (Gamma^{-1} \otimes I) Y . 67761692a83SJed Brown 67861692a83SJed Brown Note that Gamma^{-1} is lower triangular. With this definition of Ydot in terms of known quantities and the current 67961692a83SJed Brown stage y_i, the stage equations reduce to performing one Newton step (typically with a lagged Jacobian) on the 68061692a83SJed Brown equation 68161692a83SJed Brown 68261692a83SJed Brown $ g(x_0 + sum_j a_ij y_j + y_i, ydot_i) = 0 68361692a83SJed Brown 68461692a83SJed Brown with initial guess y_i = 0. 685e27a552bSJed Brown 686e27a552bSJed Brown Level: beginner 687e27a552bSJed Brown 688e27a552bSJed Brown .seealso: TSCreate(), TS, TSSetType(), TSRosWRegister() 689e27a552bSJed Brown 690e27a552bSJed Brown M*/ 691e27a552bSJed Brown EXTERN_C_BEGIN 692e27a552bSJed Brown #undef __FUNCT__ 693e27a552bSJed Brown #define __FUNCT__ "TSCreate_RosW" 694e27a552bSJed Brown PetscErrorCode TSCreate_RosW(TS ts) 695e27a552bSJed Brown { 69661692a83SJed Brown TS_RosW *ros; 697e27a552bSJed Brown PetscErrorCode ierr; 698e27a552bSJed Brown 699e27a552bSJed Brown PetscFunctionBegin; 700e27a552bSJed Brown #if !defined(PETSC_USE_DYNAMIC_LIBRARIES) 701e27a552bSJed Brown ierr = TSRosWInitializePackage(PETSC_NULL);CHKERRQ(ierr); 702e27a552bSJed Brown #endif 703e27a552bSJed Brown 704e27a552bSJed Brown ts->ops->reset = TSReset_RosW; 705e27a552bSJed Brown ts->ops->destroy = TSDestroy_RosW; 706e27a552bSJed Brown ts->ops->view = TSView_RosW; 707e27a552bSJed Brown ts->ops->setup = TSSetUp_RosW; 708e27a552bSJed Brown ts->ops->step = TSStep_RosW; 709e27a552bSJed Brown ts->ops->interpolate = TSInterpolate_RosW; 710e27a552bSJed Brown ts->ops->setfromoptions = TSSetFromOptions_RosW; 711e27a552bSJed Brown ts->ops->snesfunction = SNESTSFormFunction_RosW; 712e27a552bSJed Brown ts->ops->snesjacobian = SNESTSFormJacobian_RosW; 713e27a552bSJed Brown 71461692a83SJed Brown ierr = PetscNewLog(ts,TS_RosW,&ros);CHKERRQ(ierr); 71561692a83SJed Brown ts->data = (void*)ros; 716e27a552bSJed Brown 717e27a552bSJed Brown ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSRosWGetType_C","TSRosWGetType_RosW",TSRosWGetType_RosW);CHKERRQ(ierr); 718e27a552bSJed Brown ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSRosWSetType_C","TSRosWSetType_RosW",TSRosWSetType_RosW);CHKERRQ(ierr); 71961692a83SJed Brown ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSRosWSetRecomputeJacobian_C","TSRosWSetRecomputeJacobian_RosW",TSRosWSetRecomputeJacobian_RosW);CHKERRQ(ierr); 720e27a552bSJed Brown PetscFunctionReturn(0); 721e27a552bSJed Brown } 722e27a552bSJed Brown EXTERN_C_END 723