1 /* 2 Provides a PETSc interface to SUNDIALS/CVODE solver. 3 The interface to PVODE (old version of CVODE) was originally contributed 4 by Liyang Xu. It has been redone by Hong Zhang and Dinesh Kaushik. 5 6 Reference: sundials-2.4.0/examples/cvode/parallel/cvDiurnal_kry_p.c 7 */ 8 #include <../src/ts/impls/implicit/sundials/sundials.h> /*I "petscts.h" I*/ 9 10 /* 11 TSPrecond_Sundials - function that we provide to SUNDIALS to 12 evaluate the preconditioner. 13 */ 14 PetscErrorCode TSPrecond_Sundials(realtype tn,N_Vector y,N_Vector fy,booleantype jok,booleantype *jcurPtr, 15 realtype _gamma,void *P_data,N_Vector vtemp1,N_Vector vtemp2,N_Vector vtemp3) 16 { 17 TS ts = (TS) P_data; 18 TS_Sundials *cvode = (TS_Sundials*)ts->data; 19 PC pc; 20 PetscErrorCode ierr; 21 Mat J,P; 22 Vec yy = cvode->w1,yydot = cvode->ydot; 23 PetscReal gm = (PetscReal)_gamma; 24 PetscScalar *y_data; 25 26 PetscFunctionBegin; 27 ierr = TSGetIJacobian(ts,&J,&P,NULL,NULL);CHKERRQ(ierr); 28 y_data = (PetscScalar*) N_VGetArrayPointer(y); 29 ierr = VecPlaceArray(yy,y_data);CHKERRQ(ierr); 30 ierr = VecZeroEntries(yydot);CHKERRQ(ierr); /* The Jacobian is independent of Ydot for ODE which is all that CVode works for */ 31 /* compute the shifted Jacobian (1/gm)*I + Jrest */ 32 ierr = TSComputeIJacobian(ts,ts->ptime,yy,yydot,1/gm,J,P,PETSC_FALSE);CHKERRQ(ierr); 33 ierr = VecResetArray(yy);CHKERRQ(ierr); 34 ierr = MatScale(P,gm);CHKERRQ(ierr); /* turn into I-gm*Jrest, J is not used by Sundials */ 35 *jcurPtr = TRUE; 36 ierr = TSSundialsGetPC(ts,&pc);CHKERRQ(ierr); 37 ierr = PCSetOperators(pc,J,P);CHKERRQ(ierr); 38 PetscFunctionReturn(0); 39 } 40 41 /* 42 TSPSolve_Sundials - routine that we provide to Sundials that applies the preconditioner. 43 */ 44 PetscErrorCode TSPSolve_Sundials(realtype tn,N_Vector y,N_Vector fy,N_Vector r,N_Vector z, 45 realtype _gamma,realtype delta,int lr,void *P_data,N_Vector vtemp) 46 { 47 TS ts = (TS) P_data; 48 TS_Sundials *cvode = (TS_Sundials*)ts->data; 49 PC pc; 50 Vec rr = cvode->w1,zz = cvode->w2; 51 PetscErrorCode ierr; 52 PetscScalar *r_data,*z_data; 53 54 PetscFunctionBegin; 55 /* Make the PETSc work vectors rr and zz point to the arrays in the SUNDIALS vectors r and z respectively*/ 56 r_data = (PetscScalar*) N_VGetArrayPointer(r); 57 z_data = (PetscScalar*) N_VGetArrayPointer(z); 58 ierr = VecPlaceArray(rr,r_data);CHKERRQ(ierr); 59 ierr = VecPlaceArray(zz,z_data);CHKERRQ(ierr); 60 61 /* Solve the Px=r and put the result in zz */ 62 ierr = TSSundialsGetPC(ts,&pc);CHKERRQ(ierr); 63 ierr = PCApply(pc,rr,zz);CHKERRQ(ierr); 64 ierr = VecResetArray(rr);CHKERRQ(ierr); 65 ierr = VecResetArray(zz);CHKERRQ(ierr); 66 PetscFunctionReturn(0); 67 } 68 69 /* 70 TSFunction_Sundials - routine that we provide to Sundials that applies the right hand side. 71 */ 72 int TSFunction_Sundials(realtype t,N_Vector y,N_Vector ydot,void *ctx) 73 { 74 TS ts = (TS) ctx; 75 DM dm; 76 DMTS tsdm; 77 TSIFunction ifunction; 78 MPI_Comm comm; 79 TS_Sundials *cvode = (TS_Sundials*)ts->data; 80 Vec yy = cvode->w1,yyd = cvode->w2,yydot = cvode->ydot; 81 PetscScalar *y_data,*ydot_data; 82 PetscErrorCode ierr; 83 84 PetscFunctionBegin; 85 ierr = PetscObjectGetComm((PetscObject)ts,&comm);CHKERRQ(ierr); 86 /* Make the PETSc work vectors yy and yyd point to the arrays in the SUNDIALS vectors y and ydot respectively*/ 87 y_data = (PetscScalar*) N_VGetArrayPointer(y); 88 ydot_data = (PetscScalar*) N_VGetArrayPointer(ydot); 89 ierr = VecPlaceArray(yy,y_data);CHKERRABORT(comm,ierr); 90 ierr = VecPlaceArray(yyd,ydot_data);CHKERRABORT(comm,ierr); 91 92 /* Now compute the right hand side function, via IFunction unless only the more efficient RHSFunction is set */ 93 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 94 ierr = DMGetDMTS(dm,&tsdm);CHKERRQ(ierr); 95 ierr = DMTSGetIFunction(dm,&ifunction,NULL);CHKERRQ(ierr); 96 if (!ifunction) { 97 ierr = TSComputeRHSFunction(ts,t,yy,yyd);CHKERRQ(ierr); 98 } else { /* If rhsfunction is also set, this computes both parts and shifts them to the right */ 99 ierr = VecZeroEntries(yydot);CHKERRQ(ierr); 100 ierr = TSComputeIFunction(ts,t,yy,yydot,yyd,PETSC_FALSE);CHKERRABORT(comm,ierr); 101 ierr = VecScale(yyd,-1.);CHKERRQ(ierr); 102 } 103 ierr = VecResetArray(yy);CHKERRABORT(comm,ierr); 104 ierr = VecResetArray(yyd);CHKERRABORT(comm,ierr); 105 PetscFunctionReturn(0); 106 } 107 108 /* 109 TSStep_Sundials - Calls Sundials to integrate the ODE. 110 */ 111 PetscErrorCode TSStep_Sundials(TS ts) 112 { 113 TS_Sundials *cvode = (TS_Sundials*)ts->data; 114 PetscErrorCode ierr; 115 PetscInt flag; 116 long int nits,lits,nsteps; 117 realtype t,tout; 118 PetscScalar *y_data; 119 void *mem; 120 121 PetscFunctionBegin; 122 mem = cvode->mem; 123 tout = ts->max_time; 124 ierr = VecGetArray(ts->vec_sol,&y_data);CHKERRQ(ierr); 125 N_VSetArrayPointer((realtype*)y_data,cvode->y); 126 ierr = VecRestoreArray(ts->vec_sol,NULL);CHKERRQ(ierr); 127 128 /* We would like to TSPreStage() and TSPostStage() 129 * before each stage solve but CVode does not appear to support this. */ 130 if (cvode->monitorstep) 131 flag = CVode(mem,tout,cvode->y,&t,CV_ONE_STEP); 132 else 133 flag = CVode(mem,tout,cvode->y,&t,CV_NORMAL); 134 135 if (flag) { /* display error message */ 136 switch (flag) { 137 case CV_ILL_INPUT: 138 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"CVode() fails, CV_ILL_INPUT"); 139 break; 140 case CV_TOO_CLOSE: 141 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"CVode() fails, CV_TOO_CLOSE"); 142 break; 143 case CV_TOO_MUCH_WORK: { 144 PetscReal tcur; 145 ierr = CVodeGetNumSteps(mem,&nsteps);CHKERRQ(ierr); 146 ierr = CVodeGetCurrentTime(mem,&tcur);CHKERRQ(ierr); 147 SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_LIB,"CVode() fails, CV_TOO_MUCH_WORK. At t=%g, nsteps %D exceeds maxstep %D. Increase '-ts_max_steps <>' or modify TSSetMaxSteps()",(double)tcur,nsteps,ts->max_steps); 148 } break; 149 case CV_TOO_MUCH_ACC: 150 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"CVode() fails, CV_TOO_MUCH_ACC"); 151 break; 152 case CV_ERR_FAILURE: 153 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"CVode() fails, CV_ERR_FAILURE"); 154 break; 155 case CV_CONV_FAILURE: 156 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"CVode() fails, CV_CONV_FAILURE"); 157 break; 158 case CV_LINIT_FAIL: 159 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"CVode() fails, CV_LINIT_FAIL"); 160 break; 161 case CV_LSETUP_FAIL: 162 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"CVode() fails, CV_LSETUP_FAIL"); 163 break; 164 case CV_LSOLVE_FAIL: 165 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"CVode() fails, CV_LSOLVE_FAIL"); 166 break; 167 case CV_RHSFUNC_FAIL: 168 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"CVode() fails, CV_RHSFUNC_FAIL"); 169 break; 170 case CV_FIRST_RHSFUNC_ERR: 171 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"CVode() fails, CV_FIRST_RHSFUNC_ERR"); 172 break; 173 case CV_REPTD_RHSFUNC_ERR: 174 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"CVode() fails, CV_REPTD_RHSFUNC_ERR"); 175 break; 176 case CV_UNREC_RHSFUNC_ERR: 177 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"CVode() fails, CV_UNREC_RHSFUNC_ERR"); 178 break; 179 case CV_RTFUNC_FAIL: 180 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"CVode() fails, CV_RTFUNC_FAIL"); 181 break; 182 default: 183 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"CVode() fails, flag %d",flag); 184 } 185 } 186 187 /* log inner nonlinear and linear iterations */ 188 ierr = CVodeGetNumNonlinSolvIters(mem,&nits);CHKERRQ(ierr); 189 ierr = CVSpilsGetNumLinIters(mem,&lits);CHKERRQ(ierr); 190 ts->snes_its += nits; ts->ksp_its = lits; 191 192 /* copy the solution from cvode->y to cvode->update and sol */ 193 ierr = VecPlaceArray(cvode->w1,y_data);CHKERRQ(ierr); 194 ierr = VecCopy(cvode->w1,cvode->update);CHKERRQ(ierr); 195 ierr = VecResetArray(cvode->w1);CHKERRQ(ierr); 196 ierr = VecCopy(cvode->update,ts->vec_sol);CHKERRQ(ierr); 197 198 ts->time_step = t - ts->ptime; 199 ts->ptime = t; 200 201 ierr = CVodeGetNumSteps(mem,&nsteps);CHKERRQ(ierr); 202 if (!cvode->monitorstep) ts->steps += nsteps - 1; /* TSStep() increments the step counter by one */ 203 PetscFunctionReturn(0); 204 } 205 206 static PetscErrorCode TSInterpolate_Sundials(TS ts,PetscReal t,Vec X) 207 { 208 TS_Sundials *cvode = (TS_Sundials*)ts->data; 209 N_Vector y; 210 PetscErrorCode ierr; 211 PetscScalar *x_data; 212 PetscInt glosize,locsize; 213 214 PetscFunctionBegin; 215 /* get the vector size */ 216 ierr = VecGetSize(X,&glosize);CHKERRQ(ierr); 217 ierr = VecGetLocalSize(X,&locsize);CHKERRQ(ierr); 218 219 /* allocate the memory for N_Vec y */ 220 y = N_VNew_Parallel(cvode->comm_sundials,locsize,glosize); 221 if (!y) SETERRQ(PETSC_COMM_SELF,1,"Interpolated y is not allocated"); 222 223 ierr = VecGetArray(X,&x_data);CHKERRQ(ierr); 224 N_VSetArrayPointer((realtype*)x_data,y); 225 ierr = CVodeGetDky(cvode->mem,t,0,y);CHKERRQ(ierr); 226 ierr = VecRestoreArray(X,&x_data);CHKERRQ(ierr); 227 PetscFunctionReturn(0); 228 } 229 230 PetscErrorCode TSReset_Sundials(TS ts) 231 { 232 TS_Sundials *cvode = (TS_Sundials*)ts->data; 233 PetscErrorCode ierr; 234 235 PetscFunctionBegin; 236 ierr = VecDestroy(&cvode->update);CHKERRQ(ierr); 237 ierr = VecDestroy(&cvode->ydot);CHKERRQ(ierr); 238 ierr = VecDestroy(&cvode->w1);CHKERRQ(ierr); 239 ierr = VecDestroy(&cvode->w2);CHKERRQ(ierr); 240 if (cvode->mem) CVodeFree(&cvode->mem); 241 PetscFunctionReturn(0); 242 } 243 244 PetscErrorCode TSDestroy_Sundials(TS ts) 245 { 246 TS_Sundials *cvode = (TS_Sundials*)ts->data; 247 PetscErrorCode ierr; 248 249 PetscFunctionBegin; 250 ierr = TSReset_Sundials(ts);CHKERRQ(ierr); 251 ierr = MPI_Comm_free(&(cvode->comm_sundials));CHKERRQ(ierr); 252 ierr = PetscFree(ts->data);CHKERRQ(ierr); 253 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSundialsSetType_C",NULL);CHKERRQ(ierr); 254 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSundialsSetMaxl_C",NULL);CHKERRQ(ierr); 255 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSundialsSetLinearTolerance_C",NULL);CHKERRQ(ierr); 256 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSundialsSetGramSchmidtType_C",NULL);CHKERRQ(ierr); 257 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSundialsSetTolerance_C",NULL);CHKERRQ(ierr); 258 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSundialsSetMinTimeStep_C",NULL);CHKERRQ(ierr); 259 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSundialsSetMaxTimeStep_C",NULL);CHKERRQ(ierr); 260 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSundialsGetPC_C",NULL);CHKERRQ(ierr); 261 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSundialsGetIterations_C",NULL);CHKERRQ(ierr); 262 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSundialsMonitorInternalSteps_C",NULL);CHKERRQ(ierr); 263 PetscFunctionReturn(0); 264 } 265 266 PetscErrorCode TSSetUp_Sundials(TS ts) 267 { 268 TS_Sundials *cvode = (TS_Sundials*)ts->data; 269 PetscErrorCode ierr; 270 PetscInt glosize,locsize,i,flag; 271 PetscScalar *y_data,*parray; 272 void *mem; 273 PC pc; 274 PCType pctype; 275 PetscBool pcnone; 276 277 PetscFunctionBegin; 278 if (ts->exact_final_time == TS_EXACTFINALTIME_MATCHSTEP) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for exact final time option 'MATCHSTEP' when using Sundials"); 279 280 /* get the vector size */ 281 ierr = VecGetSize(ts->vec_sol,&glosize);CHKERRQ(ierr); 282 ierr = VecGetLocalSize(ts->vec_sol,&locsize);CHKERRQ(ierr); 283 284 /* allocate the memory for N_Vec y */ 285 cvode->y = N_VNew_Parallel(cvode->comm_sundials,locsize,glosize); 286 if (!cvode->y) SETERRQ(PETSC_COMM_SELF,1,"cvode->y is not allocated"); 287 288 /* initialize N_Vec y: copy ts->vec_sol to cvode->y */ 289 ierr = VecGetArray(ts->vec_sol,&parray);CHKERRQ(ierr); 290 y_data = (PetscScalar*) N_VGetArrayPointer(cvode->y); 291 for (i = 0; i < locsize; i++) y_data[i] = parray[i]; 292 ierr = VecRestoreArray(ts->vec_sol,NULL);CHKERRQ(ierr); 293 294 ierr = VecDuplicate(ts->vec_sol,&cvode->update);CHKERRQ(ierr); 295 ierr = VecDuplicate(ts->vec_sol,&cvode->ydot);CHKERRQ(ierr); 296 ierr = PetscLogObjectParent((PetscObject)ts,(PetscObject)cvode->update);CHKERRQ(ierr); 297 ierr = PetscLogObjectParent((PetscObject)ts,(PetscObject)cvode->ydot);CHKERRQ(ierr); 298 299 /* 300 Create work vectors for the TSPSolve_Sundials() routine. Note these are 301 allocated with zero space arrays because the actual array space is provided 302 by Sundials and set using VecPlaceArray(). 303 */ 304 ierr = VecCreateMPIWithArray(PetscObjectComm((PetscObject)ts),1,locsize,PETSC_DECIDE,0,&cvode->w1);CHKERRQ(ierr); 305 ierr = VecCreateMPIWithArray(PetscObjectComm((PetscObject)ts),1,locsize,PETSC_DECIDE,0,&cvode->w2);CHKERRQ(ierr); 306 ierr = PetscLogObjectParent((PetscObject)ts,(PetscObject)cvode->w1);CHKERRQ(ierr); 307 ierr = PetscLogObjectParent((PetscObject)ts,(PetscObject)cvode->w2);CHKERRQ(ierr); 308 309 /* Call CVodeCreate to create the solver memory and the use of a Newton iteration */ 310 mem = CVodeCreate(cvode->cvode_type, CV_NEWTON); 311 if (!mem) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"CVodeCreate() fails"); 312 cvode->mem = mem; 313 314 /* Set the pointer to user-defined data */ 315 flag = CVodeSetUserData(mem, ts); 316 if (flag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"CVodeSetUserData() fails"); 317 318 /* Sundials may choose to use a smaller initial step, but will never use a larger step. */ 319 flag = CVodeSetInitStep(mem,(realtype)ts->time_step); 320 if (flag) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_LIB,"CVodeSetInitStep() failed"); 321 if (cvode->mindt > 0) { 322 flag = CVodeSetMinStep(mem,(realtype)cvode->mindt); 323 if (flag) { 324 if (flag == CV_MEM_NULL) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_LIB,"CVodeSetMinStep() failed, cvode_mem pointer is NULL"); 325 else if (flag == CV_ILL_INPUT) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_LIB,"CVodeSetMinStep() failed, hmin is nonpositive or it exceeds the maximum allowable step size"); 326 else SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_LIB,"CVodeSetMinStep() failed"); 327 } 328 } 329 if (cvode->maxdt > 0) { 330 flag = CVodeSetMaxStep(mem,(realtype)cvode->maxdt); 331 if (flag) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_LIB,"CVodeSetMaxStep() failed"); 332 } 333 334 /* Call CVodeInit to initialize the integrator memory and specify the 335 * user's right hand side function in u'=f(t,u), the inital time T0, and 336 * the initial dependent variable vector cvode->y */ 337 flag = CVodeInit(mem,TSFunction_Sundials,ts->ptime,cvode->y); 338 if (flag) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"CVodeInit() fails, flag %d",flag); 339 340 /* specifies scalar relative and absolute tolerances */ 341 flag = CVodeSStolerances(mem,cvode->reltol,cvode->abstol); 342 if (flag) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"CVodeSStolerances() fails, flag %d",flag); 343 344 /* Specify max num of steps to be taken by cvode in its attempt to reach the next output time */ 345 flag = CVodeSetMaxNumSteps(mem,ts->max_steps); 346 if (flag) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"CVodeSetMaxNumSteps() fails, flag %d",flag); 347 348 /* call CVSpgmr to use GMRES as the linear solver. */ 349 /* setup the ode integrator with the given preconditioner */ 350 ierr = TSSundialsGetPC(ts,&pc);CHKERRQ(ierr); 351 ierr = PCGetType(pc,&pctype);CHKERRQ(ierr); 352 ierr = PetscObjectTypeCompare((PetscObject)pc,PCNONE,&pcnone);CHKERRQ(ierr); 353 if (pcnone) { 354 flag = CVSpgmr(mem,PREC_NONE,0); 355 if (flag) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"CVSpgmr() fails, flag %d",flag); 356 } else { 357 flag = CVSpgmr(mem,PREC_LEFT,cvode->maxl); 358 if (flag) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"CVSpgmr() fails, flag %d",flag); 359 360 /* Set preconditioner and solve routines Precond and PSolve, 361 and the pointer to the user-defined block data */ 362 flag = CVSpilsSetPreconditioner(mem,TSPrecond_Sundials,TSPSolve_Sundials); 363 if (flag) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"CVSpilsSetPreconditioner() fails, flag %d", flag); 364 } 365 366 flag = CVSpilsSetGSType(mem, MODIFIED_GS); 367 if (flag) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"CVSpgmrSetGSType() fails, flag %d",flag); 368 PetscFunctionReturn(0); 369 } 370 371 /* type of CVODE linear multistep method */ 372 const char *const TSSundialsLmmTypes[] = {"","ADAMS","BDF","TSSundialsLmmType","SUNDIALS_",0}; 373 /* type of G-S orthogonalization used by CVODE linear solver */ 374 const char *const TSSundialsGramSchmidtTypes[] = {"","MODIFIED","CLASSICAL","TSSundialsGramSchmidtType","SUNDIALS_",0}; 375 376 PetscErrorCode TSSetFromOptions_Sundials(PetscOptionItems *PetscOptionsObject,TS ts) 377 { 378 TS_Sundials *cvode = (TS_Sundials*)ts->data; 379 PetscErrorCode ierr; 380 int indx; 381 PetscBool flag; 382 PC pc; 383 384 PetscFunctionBegin; 385 ierr = PetscOptionsHead(PetscOptionsObject,"SUNDIALS ODE solver options");CHKERRQ(ierr); 386 ierr = PetscOptionsEList("-ts_sundials_type","Scheme","TSSundialsSetType",TSSundialsLmmTypes,3,TSSundialsLmmTypes[cvode->cvode_type],&indx,&flag);CHKERRQ(ierr); 387 if (flag) { 388 ierr = TSSundialsSetType(ts,(TSSundialsLmmType)indx);CHKERRQ(ierr); 389 } 390 ierr = PetscOptionsEList("-ts_sundials_gramschmidt_type","Type of orthogonalization","TSSundialsSetGramSchmidtType",TSSundialsGramSchmidtTypes,3,TSSundialsGramSchmidtTypes[cvode->gtype],&indx,&flag);CHKERRQ(ierr); 391 if (flag) { 392 ierr = TSSundialsSetGramSchmidtType(ts,(TSSundialsGramSchmidtType)indx);CHKERRQ(ierr); 393 } 394 ierr = PetscOptionsReal("-ts_sundials_atol","Absolute tolerance for convergence","TSSundialsSetTolerance",cvode->abstol,&cvode->abstol,NULL);CHKERRQ(ierr); 395 ierr = PetscOptionsReal("-ts_sundials_rtol","Relative tolerance for convergence","TSSundialsSetTolerance",cvode->reltol,&cvode->reltol,NULL);CHKERRQ(ierr); 396 ierr = PetscOptionsReal("-ts_sundials_mindt","Minimum step size","TSSundialsSetMinTimeStep",cvode->mindt,&cvode->mindt,NULL);CHKERRQ(ierr); 397 ierr = PetscOptionsReal("-ts_sundials_maxdt","Maximum step size","TSSundialsSetMaxTimeStep",cvode->maxdt,&cvode->maxdt,NULL);CHKERRQ(ierr); 398 ierr = PetscOptionsReal("-ts_sundials_linear_tolerance","Convergence tolerance for linear solve","TSSundialsSetLinearTolerance",cvode->linear_tol,&cvode->linear_tol,NULL);CHKERRQ(ierr); 399 ierr = PetscOptionsInt("-ts_sundials_maxl","Max dimension of the Krylov subspace","TSSundialsSetMaxl",cvode->maxl,&cvode->maxl,NULL);CHKERRQ(ierr); 400 ierr = PetscOptionsBool("-ts_sundials_monitor_steps","Monitor SUNDIALS internal steps","TSSundialsMonitorInternalSteps",cvode->monitorstep,&cvode->monitorstep,NULL);CHKERRQ(ierr); 401 ierr = PetscOptionsTail();CHKERRQ(ierr); 402 ierr = TSSundialsGetPC(ts,&pc);CHKERRQ(ierr); 403 ierr = PCSetFromOptions(pc);CHKERRQ(ierr); 404 PetscFunctionReturn(0); 405 } 406 407 PetscErrorCode TSView_Sundials(TS ts,PetscViewer viewer) 408 { 409 TS_Sundials *cvode = (TS_Sundials*)ts->data; 410 PetscErrorCode ierr; 411 char *type; 412 char atype[] = "Adams"; 413 char btype[] = "BDF: backward differentiation formula"; 414 PetscBool iascii,isstring; 415 long int nsteps,its,nfevals,nlinsetups,nfails,itmp; 416 PetscInt qlast,qcur; 417 PetscReal hinused,hlast,hcur,tcur,tolsfac; 418 PC pc; 419 420 PetscFunctionBegin; 421 if (cvode->cvode_type == SUNDIALS_ADAMS) type = atype; 422 else type = btype; 423 424 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 425 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); 426 if (iascii) { 427 ierr = PetscViewerASCIIPrintf(viewer,"Sundials integrater does not use SNES!\n");CHKERRQ(ierr); 428 ierr = PetscViewerASCIIPrintf(viewer,"Sundials integrater type %s\n",type);CHKERRQ(ierr); 429 ierr = PetscViewerASCIIPrintf(viewer,"Sundials abs tol %g rel tol %g\n",cvode->abstol,cvode->reltol);CHKERRQ(ierr); 430 ierr = PetscViewerASCIIPrintf(viewer,"Sundials linear solver tolerance factor %g\n",cvode->linear_tol);CHKERRQ(ierr); 431 ierr = PetscViewerASCIIPrintf(viewer,"Sundials max dimension of Krylov subspace %D\n",cvode->maxl);CHKERRQ(ierr); 432 if (cvode->gtype == SUNDIALS_MODIFIED_GS) { 433 ierr = PetscViewerASCIIPrintf(viewer,"Sundials using modified Gram-Schmidt for orthogonalization in GMRES\n");CHKERRQ(ierr); 434 } else { 435 ierr = PetscViewerASCIIPrintf(viewer,"Sundials using unmodified (classical) Gram-Schmidt for orthogonalization in GMRES\n");CHKERRQ(ierr); 436 } 437 if (cvode->mindt > 0) {ierr = PetscViewerASCIIPrintf(viewer,"Sundials minimum time step %g\n",cvode->mindt);CHKERRQ(ierr);} 438 if (cvode->maxdt > 0) {ierr = PetscViewerASCIIPrintf(viewer,"Sundials maximum time step %g\n",cvode->maxdt);CHKERRQ(ierr);} 439 440 /* Outputs from CVODE, CVSPILS */ 441 ierr = CVodeGetTolScaleFactor(cvode->mem,&tolsfac);CHKERRQ(ierr); 442 ierr = PetscViewerASCIIPrintf(viewer,"Sundials suggested factor for tolerance scaling %g\n",tolsfac);CHKERRQ(ierr); 443 ierr = CVodeGetIntegratorStats(cvode->mem,&nsteps,&nfevals, 444 &nlinsetups,&nfails,&qlast,&qcur, 445 &hinused,&hlast,&hcur,&tcur);CHKERRQ(ierr); 446 ierr = PetscViewerASCIIPrintf(viewer,"Sundials cumulative number of internal steps %D\n",nsteps);CHKERRQ(ierr); 447 ierr = PetscViewerASCIIPrintf(viewer,"Sundials no. of calls to rhs function %D\n",nfevals);CHKERRQ(ierr); 448 ierr = PetscViewerASCIIPrintf(viewer,"Sundials no. of calls to linear solver setup function %D\n",nlinsetups);CHKERRQ(ierr); 449 ierr = PetscViewerASCIIPrintf(viewer,"Sundials no. of error test failures %D\n",nfails);CHKERRQ(ierr); 450 451 ierr = CVodeGetNonlinSolvStats(cvode->mem,&its,&nfails);CHKERRQ(ierr); 452 ierr = PetscViewerASCIIPrintf(viewer,"Sundials no. of nonlinear solver iterations %D\n",its);CHKERRQ(ierr); 453 ierr = PetscViewerASCIIPrintf(viewer,"Sundials no. of nonlinear convergence failure %D\n",nfails);CHKERRQ(ierr); 454 455 ierr = CVSpilsGetNumLinIters(cvode->mem, &its);CHKERRQ(ierr); /* its = no. of calls to TSPrecond_Sundials() */ 456 ierr = PetscViewerASCIIPrintf(viewer,"Sundials no. of linear iterations %D\n",its);CHKERRQ(ierr); 457 ierr = CVSpilsGetNumConvFails(cvode->mem,&itmp);CHKERRQ(ierr); 458 ierr = PetscViewerASCIIPrintf(viewer,"Sundials no. of linear convergence failures %D\n",itmp);CHKERRQ(ierr); 459 460 ierr = TSSundialsGetPC(ts,&pc);CHKERRQ(ierr); 461 ierr = PCView(pc,viewer);CHKERRQ(ierr); 462 ierr = CVSpilsGetNumPrecEvals(cvode->mem,&itmp);CHKERRQ(ierr); 463 ierr = PetscViewerASCIIPrintf(viewer,"Sundials no. of preconditioner evaluations %D\n",itmp);CHKERRQ(ierr); 464 ierr = CVSpilsGetNumPrecSolves(cvode->mem,&itmp);CHKERRQ(ierr); 465 ierr = PetscViewerASCIIPrintf(viewer,"Sundials no. of preconditioner solves %D\n",itmp);CHKERRQ(ierr); 466 467 ierr = CVSpilsGetNumJtimesEvals(cvode->mem,&itmp);CHKERRQ(ierr); 468 ierr = PetscViewerASCIIPrintf(viewer,"Sundials no. of Jacobian-vector product evaluations %D\n",itmp);CHKERRQ(ierr); 469 ierr = CVSpilsGetNumRhsEvals(cvode->mem,&itmp);CHKERRQ(ierr); 470 ierr = PetscViewerASCIIPrintf(viewer,"Sundials no. of rhs calls for finite diff. Jacobian-vector evals %D\n",itmp);CHKERRQ(ierr); 471 } else if (isstring) { 472 ierr = PetscViewerStringSPrintf(viewer,"Sundials type %s",type);CHKERRQ(ierr); 473 } 474 PetscFunctionReturn(0); 475 } 476 477 478 /* --------------------------------------------------------------------------*/ 479 PetscErrorCode TSSundialsSetType_Sundials(TS ts,TSSundialsLmmType type) 480 { 481 TS_Sundials *cvode = (TS_Sundials*)ts->data; 482 483 PetscFunctionBegin; 484 cvode->cvode_type = type; 485 PetscFunctionReturn(0); 486 } 487 488 PetscErrorCode TSSundialsSetMaxl_Sundials(TS ts,PetscInt maxl) 489 { 490 TS_Sundials *cvode = (TS_Sundials*)ts->data; 491 492 PetscFunctionBegin; 493 cvode->maxl = maxl; 494 PetscFunctionReturn(0); 495 } 496 497 PetscErrorCode TSSundialsSetLinearTolerance_Sundials(TS ts,double tol) 498 { 499 TS_Sundials *cvode = (TS_Sundials*)ts->data; 500 501 PetscFunctionBegin; 502 cvode->linear_tol = tol; 503 PetscFunctionReturn(0); 504 } 505 506 PetscErrorCode TSSundialsSetGramSchmidtType_Sundials(TS ts,TSSundialsGramSchmidtType type) 507 { 508 TS_Sundials *cvode = (TS_Sundials*)ts->data; 509 510 PetscFunctionBegin; 511 cvode->gtype = type; 512 PetscFunctionReturn(0); 513 } 514 515 PetscErrorCode TSSundialsSetTolerance_Sundials(TS ts,double aabs,double rel) 516 { 517 TS_Sundials *cvode = (TS_Sundials*)ts->data; 518 519 PetscFunctionBegin; 520 if (aabs != PETSC_DECIDE) cvode->abstol = aabs; 521 if (rel != PETSC_DECIDE) cvode->reltol = rel; 522 PetscFunctionReturn(0); 523 } 524 525 PetscErrorCode TSSundialsSetMinTimeStep_Sundials(TS ts,PetscReal mindt) 526 { 527 TS_Sundials *cvode = (TS_Sundials*)ts->data; 528 529 PetscFunctionBegin; 530 cvode->mindt = mindt; 531 PetscFunctionReturn(0); 532 } 533 534 PetscErrorCode TSSundialsSetMaxTimeStep_Sundials(TS ts,PetscReal maxdt) 535 { 536 TS_Sundials *cvode = (TS_Sundials*)ts->data; 537 538 PetscFunctionBegin; 539 cvode->maxdt = maxdt; 540 PetscFunctionReturn(0); 541 } 542 PetscErrorCode TSSundialsGetPC_Sundials(TS ts,PC *pc) 543 { 544 SNES snes; 545 KSP ksp; 546 PetscErrorCode ierr; 547 548 PetscFunctionBegin; 549 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 550 ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 551 ierr = KSPGetPC(ksp,pc);CHKERRQ(ierr); 552 PetscFunctionReturn(0); 553 } 554 555 PetscErrorCode TSSundialsGetIterations_Sundials(TS ts,int *nonlin,int *lin) 556 { 557 PetscFunctionBegin; 558 if (nonlin) *nonlin = ts->snes_its; 559 if (lin) *lin = ts->ksp_its; 560 PetscFunctionReturn(0); 561 } 562 563 PetscErrorCode TSSundialsMonitorInternalSteps_Sundials(TS ts,PetscBool s) 564 { 565 TS_Sundials *cvode = (TS_Sundials*)ts->data; 566 567 PetscFunctionBegin; 568 cvode->monitorstep = s; 569 PetscFunctionReturn(0); 570 } 571 /* -------------------------------------------------------------------------------------------*/ 572 573 /*@C 574 TSSundialsGetIterations - Gets the number of nonlinear and linear iterations used so far by Sundials. 575 576 Not Collective 577 578 Input parameters: 579 . ts - the time-step context 580 581 Output Parameters: 582 + nonlin - number of nonlinear iterations 583 - lin - number of linear iterations 584 585 Level: advanced 586 587 Notes: 588 These return the number since the creation of the TS object 589 590 .keywords: non-linear iterations, linear iterations 591 592 .seealso: TSSundialsSetType(), TSSundialsSetMaxl(), 593 TSSundialsSetLinearTolerance(), TSSundialsSetGramSchmidtType(), TSSundialsSetTolerance(), 594 TSSundialsGetIterations(), TSSundialsSetType(), 595 TSSundialsSetLinearTolerance(), TSSundialsGetPC(), TSSetExactFinalTime() 596 597 @*/ 598 PetscErrorCode TSSundialsGetIterations(TS ts,int *nonlin,int *lin) 599 { 600 PetscErrorCode ierr; 601 602 PetscFunctionBegin; 603 ierr = PetscUseMethod(ts,"TSSundialsGetIterations_C",(TS,int*,int*),(ts,nonlin,lin));CHKERRQ(ierr); 604 PetscFunctionReturn(0); 605 } 606 607 /*@ 608 TSSundialsSetType - Sets the method that Sundials will use for integration. 609 610 Logically Collective on TS 611 612 Input parameters: 613 + ts - the time-step context 614 - type - one of SUNDIALS_ADAMS or SUNDIALS_BDF 615 616 Level: intermediate 617 618 .keywords: Adams, backward differentiation formula 619 620 .seealso: TSSundialsGetIterations(), TSSundialsSetMaxl(), 621 TSSundialsSetLinearTolerance(), TSSundialsSetGramSchmidtType(), TSSundialsSetTolerance(), 622 TSSundialsGetIterations(), TSSundialsSetType(), 623 TSSundialsSetLinearTolerance(), TSSundialsSetTolerance(), TSSundialsGetPC(), 624 TSSetExactFinalTime() 625 @*/ 626 PetscErrorCode TSSundialsSetType(TS ts,TSSundialsLmmType type) 627 { 628 PetscErrorCode ierr; 629 630 PetscFunctionBegin; 631 ierr = PetscTryMethod(ts,"TSSundialsSetType_C",(TS,TSSundialsLmmType),(ts,type));CHKERRQ(ierr); 632 PetscFunctionReturn(0); 633 } 634 635 /*@ 636 TSSundialsSetMaxl - Sets the dimension of the Krylov space used by 637 GMRES in the linear solver in SUNDIALS. SUNDIALS DOES NOT use restarted GMRES so 638 this is the maximum number of GMRES steps that will be used. 639 640 Logically Collective on TS 641 642 Input parameters: 643 + ts - the time-step context 644 - maxl - number of direction vectors (the dimension of Krylov subspace). 645 646 Level: advanced 647 648 .keywords: GMRES 649 650 .seealso: TSSundialsGetIterations(), TSSundialsSetType(), 651 TSSundialsSetLinearTolerance(), TSSundialsSetGramSchmidtType(), TSSundialsSetTolerance(), 652 TSSundialsGetIterations(), TSSundialsSetType(), 653 TSSundialsSetLinearTolerance(), TSSundialsSetTolerance(), TSSundialsGetPC(), 654 TSSetExactFinalTime() 655 656 @*/ 657 PetscErrorCode TSSundialsSetMaxl(TS ts,PetscInt maxl) 658 { 659 PetscErrorCode ierr; 660 661 PetscFunctionBegin; 662 PetscValidLogicalCollectiveInt(ts,maxl,2); 663 ierr = PetscTryMethod(ts,"TSSundialsSetMaxl_C",(TS,PetscInt),(ts,maxl));CHKERRQ(ierr); 664 PetscFunctionReturn(0); 665 } 666 667 /*@ 668 TSSundialsSetLinearTolerance - Sets the tolerance used to solve the linear 669 system by SUNDIALS. 670 671 Logically Collective on TS 672 673 Input parameters: 674 + ts - the time-step context 675 - tol - the factor by which the tolerance on the nonlinear solver is 676 multiplied to get the tolerance on the linear solver, .05 by default. 677 678 Level: advanced 679 680 .keywords: GMRES, linear convergence tolerance, SUNDIALS 681 682 .seealso: TSSundialsGetIterations(), TSSundialsSetType(), TSSundialsSetMaxl(), 683 TSSundialsSetGramSchmidtType(), TSSundialsSetTolerance(), 684 TSSundialsGetIterations(), TSSundialsSetType(), 685 TSSundialsSetLinearTolerance(), TSSundialsSetTolerance(), TSSundialsGetPC(), 686 TSSetExactFinalTime() 687 688 @*/ 689 PetscErrorCode TSSundialsSetLinearTolerance(TS ts,double tol) 690 { 691 PetscErrorCode ierr; 692 693 PetscFunctionBegin; 694 PetscValidLogicalCollectiveReal(ts,tol,2); 695 ierr = PetscTryMethod(ts,"TSSundialsSetLinearTolerance_C",(TS,double),(ts,tol));CHKERRQ(ierr); 696 PetscFunctionReturn(0); 697 } 698 699 /*@ 700 TSSundialsSetGramSchmidtType - Sets type of orthogonalization used 701 in GMRES method by SUNDIALS linear solver. 702 703 Logically Collective on TS 704 705 Input parameters: 706 + ts - the time-step context 707 - type - either SUNDIALS_MODIFIED_GS or SUNDIALS_CLASSICAL_GS 708 709 Level: advanced 710 711 .keywords: Sundials, orthogonalization 712 713 .seealso: TSSundialsGetIterations(), TSSundialsSetType(), TSSundialsSetMaxl(), 714 TSSundialsSetLinearTolerance(), TSSundialsSetTolerance(), 715 TSSundialsGetIterations(), TSSundialsSetType(), 716 TSSundialsSetLinearTolerance(), TSSundialsSetTolerance(), TSSundialsGetPC(), 717 TSSetExactFinalTime() 718 719 @*/ 720 PetscErrorCode TSSundialsSetGramSchmidtType(TS ts,TSSundialsGramSchmidtType type) 721 { 722 PetscErrorCode ierr; 723 724 PetscFunctionBegin; 725 ierr = PetscTryMethod(ts,"TSSundialsSetGramSchmidtType_C",(TS,TSSundialsGramSchmidtType),(ts,type));CHKERRQ(ierr); 726 PetscFunctionReturn(0); 727 } 728 729 /*@ 730 TSSundialsSetTolerance - Sets the absolute and relative tolerance used by 731 Sundials for error control. 732 733 Logically Collective on TS 734 735 Input parameters: 736 + ts - the time-step context 737 . aabs - the absolute tolerance 738 - rel - the relative tolerance 739 740 See the Cvode/Sundials users manual for exact details on these parameters. Essentially 741 these regulate the size of the error for a SINGLE timestep. 742 743 Level: intermediate 744 745 .keywords: Sundials, tolerance 746 747 .seealso: TSSundialsGetIterations(), TSSundialsSetType(), TSSundialsSetGMRESMaxl(), 748 TSSundialsSetLinearTolerance(), TSSundialsSetGramSchmidtType(), 749 TSSundialsGetIterations(), TSSundialsSetType(), 750 TSSundialsSetLinearTolerance(), TSSundialsSetTolerance(), TSSundialsGetPC(), 751 TSSetExactFinalTime() 752 753 @*/ 754 PetscErrorCode TSSundialsSetTolerance(TS ts,double aabs,double rel) 755 { 756 PetscErrorCode ierr; 757 758 PetscFunctionBegin; 759 ierr = PetscTryMethod(ts,"TSSundialsSetTolerance_C",(TS,double,double),(ts,aabs,rel));CHKERRQ(ierr); 760 PetscFunctionReturn(0); 761 } 762 763 /*@ 764 TSSundialsGetPC - Extract the PC context from a time-step context for Sundials. 765 766 Input Parameter: 767 . ts - the time-step context 768 769 Output Parameter: 770 . pc - the preconditioner context 771 772 Level: advanced 773 774 .seealso: TSSundialsGetIterations(), TSSundialsSetType(), TSSundialsSetMaxl(), 775 TSSundialsSetLinearTolerance(), TSSundialsSetGramSchmidtType(), TSSundialsSetTolerance(), 776 TSSundialsGetIterations(), TSSundialsSetType(), 777 TSSundialsSetLinearTolerance(), TSSundialsSetTolerance() 778 @*/ 779 PetscErrorCode TSSundialsGetPC(TS ts,PC *pc) 780 { 781 PetscErrorCode ierr; 782 783 PetscFunctionBegin; 784 ierr = PetscUseMethod(ts,"TSSundialsGetPC_C",(TS,PC*),(ts,pc));CHKERRQ(ierr); 785 PetscFunctionReturn(0); 786 } 787 788 /*@ 789 TSSundialsSetMinTimeStep - Smallest time step to be chosen by the adaptive controller. 790 791 Input Parameter: 792 + ts - the time-step context 793 - mindt - lowest time step if positive, negative to deactivate 794 795 Note: 796 Sundials will error if it is not possible to keep the estimated truncation error below 797 the tolerance set with TSSundialsSetTolerance() without going below this step size. 798 799 Level: beginner 800 801 .seealso: TSSundialsSetType(), TSSundialsSetTolerance(), 802 @*/ 803 PetscErrorCode TSSundialsSetMinTimeStep(TS ts,PetscReal mindt) 804 { 805 PetscErrorCode ierr; 806 807 PetscFunctionBegin; 808 ierr = PetscTryMethod(ts,"TSSundialsSetMinTimeStep_C",(TS,PetscReal),(ts,mindt));CHKERRQ(ierr); 809 PetscFunctionReturn(0); 810 } 811 812 /*@ 813 TSSundialsSetMaxTimeStep - Largest time step to be chosen by the adaptive controller. 814 815 Input Parameter: 816 + ts - the time-step context 817 - maxdt - lowest time step if positive, negative to deactivate 818 819 Level: beginner 820 821 .seealso: TSSundialsSetType(), TSSundialsSetTolerance(), 822 @*/ 823 PetscErrorCode TSSundialsSetMaxTimeStep(TS ts,PetscReal maxdt) 824 { 825 PetscErrorCode ierr; 826 827 PetscFunctionBegin; 828 ierr = PetscTryMethod(ts,"TSSundialsSetMaxTimeStep_C",(TS,PetscReal),(ts,maxdt));CHKERRQ(ierr); 829 PetscFunctionReturn(0); 830 } 831 832 /*@ 833 TSSundialsMonitorInternalSteps - Monitor Sundials internal steps (Defaults to false). 834 835 Input Parameter: 836 + ts - the time-step context 837 - ft - PETSC_TRUE if monitor, else PETSC_FALSE 838 839 Level: beginner 840 841 .seealso:TSSundialsGetIterations(), TSSundialsSetType(), TSSundialsSetMaxl(), 842 TSSundialsSetLinearTolerance(), TSSundialsSetGramSchmidtType(), TSSundialsSetTolerance(), 843 TSSundialsGetIterations(), TSSundialsSetType(), 844 TSSundialsSetLinearTolerance(), TSSundialsSetTolerance(), TSSundialsGetPC() 845 @*/ 846 PetscErrorCode TSSundialsMonitorInternalSteps(TS ts,PetscBool ft) 847 { 848 PetscErrorCode ierr; 849 850 PetscFunctionBegin; 851 ierr = PetscTryMethod(ts,"TSSundialsMonitorInternalSteps_C",(TS,PetscBool),(ts,ft));CHKERRQ(ierr); 852 PetscFunctionReturn(0); 853 } 854 /* -------------------------------------------------------------------------------------------*/ 855 /*MC 856 TSSUNDIALS - ODE solver using the LLNL CVODE/SUNDIALS package (now called SUNDIALS) 857 858 Options Database: 859 + -ts_sundials_type <bdf,adams> - 860 . -ts_sundials_gramschmidt_type <modified, classical> - type of orthogonalization inside GMRES 861 . -ts_sundials_atol <tol> - Absolute tolerance for convergence 862 . -ts_sundials_rtol <tol> - Relative tolerance for convergence 863 . -ts_sundials_linear_tolerance <tol> - 864 . -ts_sundials_maxl <maxl> - Max dimension of the Krylov subspace 865 - -ts_sundials_monitor_steps - Monitor SUNDIALS internal steps 866 867 868 Notes: This uses its own nonlinear solver and Krylov method so PETSc SNES and KSP options do not apply, 869 only PETSc PC options. 870 871 Level: beginner 872 873 .seealso: TSCreate(), TS, TSSetType(), TSSundialsSetType(), TSSundialsSetMaxl(), TSSundialsSetLinearTolerance(), 874 TSSundialsSetGramSchmidtType(), TSSundialsSetTolerance(), TSSundialsGetPC(), TSSundialsGetIterations(), TSSetExactFinalTime() 875 876 M*/ 877 PETSC_EXTERN PetscErrorCode TSCreate_Sundials(TS ts) 878 { 879 TS_Sundials *cvode; 880 PetscErrorCode ierr; 881 PC pc; 882 883 PetscFunctionBegin; 884 ts->ops->reset = TSReset_Sundials; 885 ts->ops->destroy = TSDestroy_Sundials; 886 ts->ops->view = TSView_Sundials; 887 ts->ops->setup = TSSetUp_Sundials; 888 ts->ops->step = TSStep_Sundials; 889 ts->ops->interpolate = TSInterpolate_Sundials; 890 ts->ops->setfromoptions = TSSetFromOptions_Sundials; 891 ts->default_adapt_type = TSADAPTNONE; 892 893 ierr = PetscNewLog(ts,&cvode);CHKERRQ(ierr); 894 895 ts->usessnes = PETSC_TRUE; 896 897 ts->data = (void*)cvode; 898 cvode->cvode_type = SUNDIALS_BDF; 899 cvode->gtype = SUNDIALS_CLASSICAL_GS; 900 cvode->maxl = 5; 901 cvode->linear_tol = .05; 902 cvode->monitorstep = PETSC_TRUE; 903 904 ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)ts),&(cvode->comm_sundials));CHKERRQ(ierr); 905 906 cvode->mindt = -1.; 907 cvode->maxdt = -1.; 908 909 /* set tolerance for Sundials */ 910 cvode->reltol = 1e-6; 911 cvode->abstol = 1e-6; 912 913 /* set PCNONE as default pctype */ 914 ierr = TSSundialsGetPC_Sundials(ts,&pc);CHKERRQ(ierr); 915 ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr); 916 917 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSundialsSetType_C",TSSundialsSetType_Sundials);CHKERRQ(ierr); 918 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSundialsSetMaxl_C",TSSundialsSetMaxl_Sundials);CHKERRQ(ierr); 919 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSundialsSetLinearTolerance_C",TSSundialsSetLinearTolerance_Sundials);CHKERRQ(ierr); 920 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSundialsSetGramSchmidtType_C",TSSundialsSetGramSchmidtType_Sundials);CHKERRQ(ierr); 921 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSundialsSetTolerance_C",TSSundialsSetTolerance_Sundials);CHKERRQ(ierr); 922 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSundialsSetMinTimeStep_C",TSSundialsSetMinTimeStep_Sundials);CHKERRQ(ierr); 923 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSundialsSetMaxTimeStep_C",TSSundialsSetMaxTimeStep_Sundials);CHKERRQ(ierr); 924 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSundialsGetPC_C",TSSundialsGetPC_Sundials);CHKERRQ(ierr); 925 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSundialsGetIterations_C",TSSundialsGetIterations_Sundials);CHKERRQ(ierr); 926 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSundialsMonitorInternalSteps_C",TSSundialsMonitorInternalSteps_Sundials);CHKERRQ(ierr); 927 PetscFunctionReturn(0); 928 } 929