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 ierr = VecGetArray(X,&x_data);CHKERRQ(ierr); 219 220 /* Initialize N_Vec y with x_data */ 221 y = N_VMake_Parallel(cvode->comm_sundials,locsize,glosize,(realtype*)x_data); 222 if (!y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Interpolated y is not allocated"); 223 224 ierr = CVodeGetDky(cvode->mem,t,0,y);CHKERRQ(ierr); 225 ierr = VecRestoreArray(X,&x_data);CHKERRQ(ierr); 226 PetscFunctionReturn(0); 227 } 228 229 PetscErrorCode TSReset_Sundials(TS ts) 230 { 231 TS_Sundials *cvode = (TS_Sundials*)ts->data; 232 PetscErrorCode ierr; 233 234 PetscFunctionBegin; 235 ierr = VecDestroy(&cvode->update);CHKERRQ(ierr); 236 ierr = VecDestroy(&cvode->ydot);CHKERRQ(ierr); 237 ierr = VecDestroy(&cvode->w1);CHKERRQ(ierr); 238 ierr = VecDestroy(&cvode->w2);CHKERRQ(ierr); 239 if (cvode->mem) CVodeFree(&cvode->mem); 240 PetscFunctionReturn(0); 241 } 242 243 PetscErrorCode TSDestroy_Sundials(TS ts) 244 { 245 TS_Sundials *cvode = (TS_Sundials*)ts->data; 246 PetscErrorCode ierr; 247 248 PetscFunctionBegin; 249 ierr = TSReset_Sundials(ts);CHKERRQ(ierr); 250 ierr = MPI_Comm_free(&(cvode->comm_sundials));CHKERRQ(ierr); 251 ierr = PetscFree(ts->data);CHKERRQ(ierr); 252 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSundialsSetType_C",NULL);CHKERRQ(ierr); 253 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSundialsSetMaxl_C",NULL);CHKERRQ(ierr); 254 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSundialsSetLinearTolerance_C",NULL);CHKERRQ(ierr); 255 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSundialsSetGramSchmidtType_C",NULL);CHKERRQ(ierr); 256 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSundialsSetTolerance_C",NULL);CHKERRQ(ierr); 257 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSundialsSetMinTimeStep_C",NULL);CHKERRQ(ierr); 258 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSundialsSetMaxTimeStep_C",NULL);CHKERRQ(ierr); 259 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSundialsGetPC_C",NULL);CHKERRQ(ierr); 260 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSundialsGetIterations_C",NULL);CHKERRQ(ierr); 261 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSundialsMonitorInternalSteps_C",NULL);CHKERRQ(ierr); 262 PetscFunctionReturn(0); 263 } 264 265 PetscErrorCode TSSetUp_Sundials(TS ts) 266 { 267 TS_Sundials *cvode = (TS_Sundials*)ts->data; 268 PetscErrorCode ierr; 269 PetscInt glosize,locsize,i,flag; 270 PetscScalar *y_data,*parray; 271 void *mem; 272 PC pc; 273 PCType pctype; 274 PetscBool pcnone; 275 276 PetscFunctionBegin; 277 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"); 278 279 /* get the vector size */ 280 ierr = VecGetSize(ts->vec_sol,&glosize);CHKERRQ(ierr); 281 ierr = VecGetLocalSize(ts->vec_sol,&locsize);CHKERRQ(ierr); 282 283 /* allocate the memory for N_Vec y */ 284 cvode->y = N_VNew_Parallel(cvode->comm_sundials,locsize,glosize); 285 if (!cvode->y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"cvode->y is not allocated"); 286 287 /* initialize N_Vec y: copy ts->vec_sol to cvode->y */ 288 ierr = VecGetArray(ts->vec_sol,&parray);CHKERRQ(ierr); 289 y_data = (PetscScalar*) N_VGetArrayPointer(cvode->y); 290 for (i = 0; i < locsize; i++) y_data[i] = parray[i]; 291 ierr = VecRestoreArray(ts->vec_sol,NULL);CHKERRQ(ierr); 292 293 ierr = VecDuplicate(ts->vec_sol,&cvode->update);CHKERRQ(ierr); 294 ierr = VecDuplicate(ts->vec_sol,&cvode->ydot);CHKERRQ(ierr); 295 ierr = PetscLogObjectParent((PetscObject)ts,(PetscObject)cvode->update);CHKERRQ(ierr); 296 ierr = PetscLogObjectParent((PetscObject)ts,(PetscObject)cvode->ydot);CHKERRQ(ierr); 297 298 /* 299 Create work vectors for the TSPSolve_Sundials() routine. Note these are 300 allocated with zero space arrays because the actual array space is provided 301 by Sundials and set using VecPlaceArray(). 302 */ 303 ierr = VecCreateMPIWithArray(PetscObjectComm((PetscObject)ts),1,locsize,PETSC_DECIDE,0,&cvode->w1);CHKERRQ(ierr); 304 ierr = VecCreateMPIWithArray(PetscObjectComm((PetscObject)ts),1,locsize,PETSC_DECIDE,0,&cvode->w2);CHKERRQ(ierr); 305 ierr = PetscLogObjectParent((PetscObject)ts,(PetscObject)cvode->w1);CHKERRQ(ierr); 306 ierr = PetscLogObjectParent((PetscObject)ts,(PetscObject)cvode->w2);CHKERRQ(ierr); 307 308 /* Call CVodeCreate to create the solver memory and the use of a Newton iteration */ 309 mem = CVodeCreate(cvode->cvode_type, CV_NEWTON); 310 if (!mem) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"CVodeCreate() fails"); 311 cvode->mem = mem; 312 313 /* Set the pointer to user-defined data */ 314 flag = CVodeSetUserData(mem, ts); 315 if (flag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"CVodeSetUserData() fails"); 316 317 /* Sundials may choose to use a smaller initial step, but will never use a larger step. */ 318 flag = CVodeSetInitStep(mem,(realtype)ts->time_step); 319 if (flag) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_LIB,"CVodeSetInitStep() failed"); 320 if (cvode->mindt > 0) { 321 flag = CVodeSetMinStep(mem,(realtype)cvode->mindt); 322 if (flag) { 323 if (flag == CV_MEM_NULL) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_LIB,"CVodeSetMinStep() failed, cvode_mem pointer is NULL"); 324 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"); 325 else SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_LIB,"CVodeSetMinStep() failed"); 326 } 327 } 328 if (cvode->maxdt > 0) { 329 flag = CVodeSetMaxStep(mem,(realtype)cvode->maxdt); 330 if (flag) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_LIB,"CVodeSetMaxStep() failed"); 331 } 332 333 /* Call CVodeInit to initialize the integrator memory and specify the 334 * user's right hand side function in u'=f(t,u), the inital time T0, and 335 * the initial dependent variable vector cvode->y */ 336 flag = CVodeInit(mem,TSFunction_Sundials,ts->ptime,cvode->y); 337 if (flag) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"CVodeInit() fails, flag %d",flag); 338 339 /* specifies scalar relative and absolute tolerances */ 340 flag = CVodeSStolerances(mem,cvode->reltol,cvode->abstol); 341 if (flag) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"CVodeSStolerances() fails, flag %d",flag); 342 343 /* Specify max order of BDF / ADAMS method */ 344 if (cvode->maxord != PETSC_DEFAULT) { 345 flag = CVodeSetMaxOrd(mem,cvode->maxord); 346 if (flag) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"CVodeSetMaxOrd() fails, flag %d",flag); 347 } 348 349 /* Specify max num of steps to be taken by cvode in its attempt to reach the next output time */ 350 flag = CVodeSetMaxNumSteps(mem,ts->max_steps); 351 if (flag) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"CVodeSetMaxNumSteps() fails, flag %d",flag); 352 353 /* call CVSpgmr to use GMRES as the linear solver. */ 354 /* setup the ode integrator with the given preconditioner */ 355 ierr = TSSundialsGetPC(ts,&pc);CHKERRQ(ierr); 356 ierr = PCGetType(pc,&pctype);CHKERRQ(ierr); 357 ierr = PetscObjectTypeCompare((PetscObject)pc,PCNONE,&pcnone);CHKERRQ(ierr); 358 if (pcnone) { 359 flag = CVSpgmr(mem,PREC_NONE,0); 360 if (flag) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"CVSpgmr() fails, flag %d",flag); 361 } else { 362 flag = CVSpgmr(mem,PREC_LEFT,cvode->maxl); 363 if (flag) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"CVSpgmr() fails, flag %d",flag); 364 365 /* Set preconditioner and solve routines Precond and PSolve, 366 and the pointer to the user-defined block data */ 367 flag = CVSpilsSetPreconditioner(mem,TSPrecond_Sundials,TSPSolve_Sundials); 368 if (flag) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"CVSpilsSetPreconditioner() fails, flag %d", flag); 369 } 370 371 flag = CVSpilsSetGSType(mem, MODIFIED_GS); 372 if (flag) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"CVSpgmrSetGSType() fails, flag %d",flag); 373 PetscFunctionReturn(0); 374 } 375 376 /* type of CVODE linear multistep method */ 377 const char *const TSSundialsLmmTypes[] = {"","ADAMS","BDF","TSSundialsLmmType","SUNDIALS_",0}; 378 /* type of G-S orthogonalization used by CVODE linear solver */ 379 const char *const TSSundialsGramSchmidtTypes[] = {"","MODIFIED","CLASSICAL","TSSundialsGramSchmidtType","SUNDIALS_",0}; 380 381 PetscErrorCode TSSetFromOptions_Sundials(PetscOptionItems *PetscOptionsObject,TS ts) 382 { 383 TS_Sundials *cvode = (TS_Sundials*)ts->data; 384 PetscErrorCode ierr; 385 int indx; 386 PetscBool flag; 387 PC pc; 388 389 PetscFunctionBegin; 390 ierr = PetscOptionsHead(PetscOptionsObject,"SUNDIALS ODE solver options");CHKERRQ(ierr); 391 ierr = PetscOptionsEList("-ts_sundials_type","Scheme","TSSundialsSetType",TSSundialsLmmTypes,3,TSSundialsLmmTypes[cvode->cvode_type],&indx,&flag);CHKERRQ(ierr); 392 if (flag) { 393 ierr = TSSundialsSetType(ts,(TSSundialsLmmType)indx);CHKERRQ(ierr); 394 } 395 ierr = PetscOptionsEList("-ts_sundials_gramschmidt_type","Type of orthogonalization","TSSundialsSetGramSchmidtType",TSSundialsGramSchmidtTypes,3,TSSundialsGramSchmidtTypes[cvode->gtype],&indx,&flag);CHKERRQ(ierr); 396 if (flag) { 397 ierr = TSSundialsSetGramSchmidtType(ts,(TSSundialsGramSchmidtType)indx);CHKERRQ(ierr); 398 } 399 ierr = PetscOptionsReal("-ts_sundials_atol","Absolute tolerance for convergence","TSSundialsSetTolerance",cvode->abstol,&cvode->abstol,NULL);CHKERRQ(ierr); 400 ierr = PetscOptionsReal("-ts_sundials_rtol","Relative tolerance for convergence","TSSundialsSetTolerance",cvode->reltol,&cvode->reltol,NULL);CHKERRQ(ierr); 401 ierr = PetscOptionsReal("-ts_sundials_mindt","Minimum step size","TSSundialsSetMinTimeStep",cvode->mindt,&cvode->mindt,NULL);CHKERRQ(ierr); 402 ierr = PetscOptionsReal("-ts_sundials_maxdt","Maximum step size","TSSundialsSetMaxTimeStep",cvode->maxdt,&cvode->maxdt,NULL);CHKERRQ(ierr); 403 ierr = PetscOptionsReal("-ts_sundials_linear_tolerance","Convergence tolerance for linear solve","TSSundialsSetLinearTolerance",cvode->linear_tol,&cvode->linear_tol,NULL);CHKERRQ(ierr); 404 ierr = PetscOptionsInt("-ts_sundials_maxord","Max Order for BDF/Adams method","TSSundialsSetMaxOrd",cvode->maxord,&cvode->maxord,NULL);CHKERRQ(ierr); 405 ierr = PetscOptionsInt("-ts_sundials_maxl","Max dimension of the Krylov subspace","TSSundialsSetMaxl",cvode->maxl,&cvode->maxl,NULL);CHKERRQ(ierr); 406 ierr = PetscOptionsBool("-ts_sundials_monitor_steps","Monitor SUNDIALS internal steps","TSSundialsMonitorInternalSteps",cvode->monitorstep,&cvode->monitorstep,NULL);CHKERRQ(ierr); 407 ierr = PetscOptionsTail();CHKERRQ(ierr); 408 ierr = TSSundialsGetPC(ts,&pc);CHKERRQ(ierr); 409 ierr = PCSetFromOptions(pc);CHKERRQ(ierr); 410 PetscFunctionReturn(0); 411 } 412 413 PetscErrorCode TSView_Sundials(TS ts,PetscViewer viewer) 414 { 415 TS_Sundials *cvode = (TS_Sundials*)ts->data; 416 PetscErrorCode ierr; 417 char *type; 418 char atype[] = "Adams"; 419 char btype[] = "BDF: backward differentiation formula"; 420 PetscBool iascii,isstring; 421 long int nsteps,its,nfevals,nlinsetups,nfails,itmp; 422 PetscInt qlast,qcur; 423 PetscReal hinused,hlast,hcur,tcur,tolsfac; 424 PC pc; 425 426 PetscFunctionBegin; 427 if (cvode->cvode_type == SUNDIALS_ADAMS) type = atype; 428 else type = btype; 429 430 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 431 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); 432 if (iascii) { 433 ierr = PetscViewerASCIIPrintf(viewer,"Sundials integrater does not use SNES!\n");CHKERRQ(ierr); 434 ierr = PetscViewerASCIIPrintf(viewer,"Sundials integrater type %s\n",type);CHKERRQ(ierr); 435 ierr = PetscViewerASCIIPrintf(viewer,"Sundials maxord %D\n",cvode->maxord);CHKERRQ(ierr); 436 ierr = PetscViewerASCIIPrintf(viewer,"Sundials abs tol %g rel tol %g\n",(double)cvode->abstol,(double)cvode->reltol);CHKERRQ(ierr); 437 ierr = PetscViewerASCIIPrintf(viewer,"Sundials linear solver tolerance factor %g\n",(double)cvode->linear_tol);CHKERRQ(ierr); 438 ierr = PetscViewerASCIIPrintf(viewer,"Sundials max dimension of Krylov subspace %D\n",cvode->maxl);CHKERRQ(ierr); 439 if (cvode->gtype == SUNDIALS_MODIFIED_GS) { 440 ierr = PetscViewerASCIIPrintf(viewer,"Sundials using modified Gram-Schmidt for orthogonalization in GMRES\n");CHKERRQ(ierr); 441 } else { 442 ierr = PetscViewerASCIIPrintf(viewer,"Sundials using unmodified (classical) Gram-Schmidt for orthogonalization in GMRES\n");CHKERRQ(ierr); 443 } 444 if (cvode->mindt > 0) {ierr = PetscViewerASCIIPrintf(viewer,"Sundials minimum time step %g\n",(double)cvode->mindt);CHKERRQ(ierr);} 445 if (cvode->maxdt > 0) {ierr = PetscViewerASCIIPrintf(viewer,"Sundials maximum time step %g\n",(double)cvode->maxdt);CHKERRQ(ierr);} 446 447 /* Outputs from CVODE, CVSPILS */ 448 ierr = CVodeGetTolScaleFactor(cvode->mem,&tolsfac);CHKERRQ(ierr); 449 ierr = PetscViewerASCIIPrintf(viewer,"Sundials suggested factor for tolerance scaling %g\n",tolsfac);CHKERRQ(ierr); 450 ierr = CVodeGetIntegratorStats(cvode->mem,&nsteps,&nfevals, 451 &nlinsetups,&nfails,&qlast,&qcur, 452 &hinused,&hlast,&hcur,&tcur);CHKERRQ(ierr); 453 ierr = PetscViewerASCIIPrintf(viewer,"Sundials cumulative number of internal steps %D\n",nsteps);CHKERRQ(ierr); 454 ierr = PetscViewerASCIIPrintf(viewer,"Sundials no. of calls to rhs function %D\n",nfevals);CHKERRQ(ierr); 455 ierr = PetscViewerASCIIPrintf(viewer,"Sundials no. of calls to linear solver setup function %D\n",nlinsetups);CHKERRQ(ierr); 456 ierr = PetscViewerASCIIPrintf(viewer,"Sundials no. of error test failures %D\n",nfails);CHKERRQ(ierr); 457 458 ierr = CVodeGetNonlinSolvStats(cvode->mem,&its,&nfails);CHKERRQ(ierr); 459 ierr = PetscViewerASCIIPrintf(viewer,"Sundials no. of nonlinear solver iterations %D\n",its);CHKERRQ(ierr); 460 ierr = PetscViewerASCIIPrintf(viewer,"Sundials no. of nonlinear convergence failure %D\n",nfails);CHKERRQ(ierr); 461 462 ierr = CVSpilsGetNumLinIters(cvode->mem, &its);CHKERRQ(ierr); /* its = no. of calls to TSPrecond_Sundials() */ 463 ierr = PetscViewerASCIIPrintf(viewer,"Sundials no. of linear iterations %D\n",its);CHKERRQ(ierr); 464 ierr = CVSpilsGetNumConvFails(cvode->mem,&itmp);CHKERRQ(ierr); 465 ierr = PetscViewerASCIIPrintf(viewer,"Sundials no. of linear convergence failures %D\n",itmp);CHKERRQ(ierr); 466 467 ierr = TSSundialsGetPC(ts,&pc);CHKERRQ(ierr); 468 ierr = PCView(pc,viewer);CHKERRQ(ierr); 469 ierr = CVSpilsGetNumPrecEvals(cvode->mem,&itmp);CHKERRQ(ierr); 470 ierr = PetscViewerASCIIPrintf(viewer,"Sundials no. of preconditioner evaluations %D\n",itmp);CHKERRQ(ierr); 471 ierr = CVSpilsGetNumPrecSolves(cvode->mem,&itmp);CHKERRQ(ierr); 472 ierr = PetscViewerASCIIPrintf(viewer,"Sundials no. of preconditioner solves %D\n",itmp);CHKERRQ(ierr); 473 474 ierr = CVSpilsGetNumJtimesEvals(cvode->mem,&itmp);CHKERRQ(ierr); 475 ierr = PetscViewerASCIIPrintf(viewer,"Sundials no. of Jacobian-vector product evaluations %D\n",itmp);CHKERRQ(ierr); 476 ierr = CVSpilsGetNumRhsEvals(cvode->mem,&itmp);CHKERRQ(ierr); 477 ierr = PetscViewerASCIIPrintf(viewer,"Sundials no. of rhs calls for finite diff. Jacobian-vector evals %D\n",itmp);CHKERRQ(ierr); 478 } else if (isstring) { 479 ierr = PetscViewerStringSPrintf(viewer,"Sundials type %s",type);CHKERRQ(ierr); 480 } 481 PetscFunctionReturn(0); 482 } 483 484 485 /* --------------------------------------------------------------------------*/ 486 PetscErrorCode TSSundialsSetType_Sundials(TS ts,TSSundialsLmmType type) 487 { 488 TS_Sundials *cvode = (TS_Sundials*)ts->data; 489 490 PetscFunctionBegin; 491 cvode->cvode_type = type; 492 PetscFunctionReturn(0); 493 } 494 495 PetscErrorCode TSSundialsSetMaxl_Sundials(TS ts,PetscInt maxl) 496 { 497 TS_Sundials *cvode = (TS_Sundials*)ts->data; 498 499 PetscFunctionBegin; 500 cvode->maxl = maxl; 501 PetscFunctionReturn(0); 502 } 503 504 PetscErrorCode TSSundialsSetLinearTolerance_Sundials(TS ts,double tol) 505 { 506 TS_Sundials *cvode = (TS_Sundials*)ts->data; 507 508 PetscFunctionBegin; 509 cvode->linear_tol = tol; 510 PetscFunctionReturn(0); 511 } 512 513 PetscErrorCode TSSundialsSetGramSchmidtType_Sundials(TS ts,TSSundialsGramSchmidtType type) 514 { 515 TS_Sundials *cvode = (TS_Sundials*)ts->data; 516 517 PetscFunctionBegin; 518 cvode->gtype = type; 519 PetscFunctionReturn(0); 520 } 521 522 PetscErrorCode TSSundialsSetTolerance_Sundials(TS ts,double aabs,double rel) 523 { 524 TS_Sundials *cvode = (TS_Sundials*)ts->data; 525 526 PetscFunctionBegin; 527 if (aabs != PETSC_DECIDE) cvode->abstol = aabs; 528 if (rel != PETSC_DECIDE) cvode->reltol = rel; 529 PetscFunctionReturn(0); 530 } 531 532 PetscErrorCode TSSundialsSetMinTimeStep_Sundials(TS ts,PetscReal mindt) 533 { 534 TS_Sundials *cvode = (TS_Sundials*)ts->data; 535 536 PetscFunctionBegin; 537 cvode->mindt = mindt; 538 PetscFunctionReturn(0); 539 } 540 541 PetscErrorCode TSSundialsSetMaxTimeStep_Sundials(TS ts,PetscReal maxdt) 542 { 543 TS_Sundials *cvode = (TS_Sundials*)ts->data; 544 545 PetscFunctionBegin; 546 cvode->maxdt = maxdt; 547 PetscFunctionReturn(0); 548 } 549 PetscErrorCode TSSundialsGetPC_Sundials(TS ts,PC *pc) 550 { 551 SNES snes; 552 KSP ksp; 553 PetscErrorCode ierr; 554 555 PetscFunctionBegin; 556 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 557 ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 558 ierr = KSPGetPC(ksp,pc);CHKERRQ(ierr); 559 PetscFunctionReturn(0); 560 } 561 562 PetscErrorCode TSSundialsGetIterations_Sundials(TS ts,int *nonlin,int *lin) 563 { 564 PetscFunctionBegin; 565 if (nonlin) *nonlin = ts->snes_its; 566 if (lin) *lin = ts->ksp_its; 567 PetscFunctionReturn(0); 568 } 569 570 PetscErrorCode TSSundialsMonitorInternalSteps_Sundials(TS ts,PetscBool s) 571 { 572 TS_Sundials *cvode = (TS_Sundials*)ts->data; 573 574 PetscFunctionBegin; 575 cvode->monitorstep = s; 576 PetscFunctionReturn(0); 577 } 578 /* -------------------------------------------------------------------------------------------*/ 579 580 /*@C 581 TSSundialsGetIterations - Gets the number of nonlinear and linear iterations used so far by Sundials. 582 583 Not Collective 584 585 Input parameters: 586 . ts - the time-step context 587 588 Output Parameters: 589 + nonlin - number of nonlinear iterations 590 - lin - number of linear iterations 591 592 Level: advanced 593 594 Notes: 595 These return the number since the creation of the TS object 596 597 .seealso: TSSundialsSetType(), TSSundialsSetMaxl(), 598 TSSundialsSetLinearTolerance(), TSSundialsSetGramSchmidtType(), TSSundialsSetTolerance(), 599 TSSundialsGetIterations(), TSSundialsSetType(), 600 TSSundialsSetLinearTolerance(), TSSundialsGetPC(), TSSetExactFinalTime() 601 602 @*/ 603 PetscErrorCode TSSundialsGetIterations(TS ts,int *nonlin,int *lin) 604 { 605 PetscErrorCode ierr; 606 607 PetscFunctionBegin; 608 ierr = PetscUseMethod(ts,"TSSundialsGetIterations_C",(TS,int*,int*),(ts,nonlin,lin));CHKERRQ(ierr); 609 PetscFunctionReturn(0); 610 } 611 612 /*@ 613 TSSundialsSetType - Sets the method that Sundials will use for integration. 614 615 Logically Collective on TS 616 617 Input parameters: 618 + ts - the time-step context 619 - type - one of SUNDIALS_ADAMS or SUNDIALS_BDF 620 621 Level: intermediate 622 623 .seealso: TSSundialsGetIterations(), TSSundialsSetMaxl(), 624 TSSundialsSetLinearTolerance(), TSSundialsSetGramSchmidtType(), TSSundialsSetTolerance(), 625 TSSundialsGetIterations(), TSSundialsSetType(), 626 TSSundialsSetLinearTolerance(), TSSundialsSetTolerance(), TSSundialsGetPC(), 627 TSSetExactFinalTime() 628 @*/ 629 PetscErrorCode TSSundialsSetType(TS ts,TSSundialsLmmType type) 630 { 631 PetscErrorCode ierr; 632 633 PetscFunctionBegin; 634 ierr = PetscTryMethod(ts,"TSSundialsSetType_C",(TS,TSSundialsLmmType),(ts,type));CHKERRQ(ierr); 635 PetscFunctionReturn(0); 636 } 637 638 /*@ 639 TSSundialsSetMaxord - Sets the maximum order for BDF/Adams method used by SUNDIALS. 640 641 Logically Collective on TS 642 643 Input parameters: 644 + ts - the time-step context 645 - maxord - maximum order of BDF / Adams method 646 647 Level: advanced 648 649 .seealso: TSSundialsGetIterations(), TSSundialsSetType(), 650 TSSundialsSetLinearTolerance(), TSSundialsSetGramSchmidtType(), TSSundialsSetTolerance(), 651 TSSundialsGetIterations(), TSSundialsSetType(), 652 TSSundialsSetLinearTolerance(), TSSundialsSetTolerance(), TSSundialsGetPC(), 653 TSSetExactFinalTime() 654 655 @*/ 656 PetscErrorCode TSSundialsSetMaxord(TS ts,PetscInt maxord) 657 { 658 PetscErrorCode ierr; 659 660 PetscFunctionBegin; 661 PetscValidLogicalCollectiveInt(ts,maxord,2); 662 ierr = PetscTryMethod(ts,"TSSundialsSetMaxOrd_C",(TS,PetscInt),(ts,maxord));CHKERRQ(ierr); 663 PetscFunctionReturn(0); 664 } 665 666 /*@ 667 TSSundialsSetMaxl - Sets the dimension of the Krylov space used by 668 GMRES in the linear solver in SUNDIALS. SUNDIALS DOES NOT use restarted GMRES so 669 this is the maximum number of GMRES steps that will be used. 670 671 Logically Collective on TS 672 673 Input parameters: 674 + ts - the time-step context 675 - maxl - number of direction vectors (the dimension of Krylov subspace). 676 677 Level: advanced 678 679 .seealso: TSSundialsGetIterations(), TSSundialsSetType(), 680 TSSundialsSetLinearTolerance(), TSSundialsSetGramSchmidtType(), TSSundialsSetTolerance(), 681 TSSundialsGetIterations(), TSSundialsSetType(), 682 TSSundialsSetLinearTolerance(), TSSundialsSetTolerance(), TSSundialsGetPC(), 683 TSSetExactFinalTime() 684 685 @*/ 686 PetscErrorCode TSSundialsSetMaxl(TS ts,PetscInt maxl) 687 { 688 PetscErrorCode ierr; 689 690 PetscFunctionBegin; 691 PetscValidLogicalCollectiveInt(ts,maxl,2); 692 ierr = PetscTryMethod(ts,"TSSundialsSetMaxl_C",(TS,PetscInt),(ts,maxl));CHKERRQ(ierr); 693 PetscFunctionReturn(0); 694 } 695 696 /*@ 697 TSSundialsSetLinearTolerance - Sets the tolerance used to solve the linear 698 system by SUNDIALS. 699 700 Logically Collective on TS 701 702 Input parameters: 703 + ts - the time-step context 704 - tol - the factor by which the tolerance on the nonlinear solver is 705 multiplied to get the tolerance on the linear solver, .05 by default. 706 707 Level: advanced 708 709 .seealso: TSSundialsGetIterations(), TSSundialsSetType(), TSSundialsSetMaxl(), 710 TSSundialsSetGramSchmidtType(), TSSundialsSetTolerance(), 711 TSSundialsGetIterations(), TSSundialsSetType(), 712 TSSundialsSetLinearTolerance(), TSSundialsSetTolerance(), TSSundialsGetPC(), 713 TSSetExactFinalTime() 714 715 @*/ 716 PetscErrorCode TSSundialsSetLinearTolerance(TS ts,double tol) 717 { 718 PetscErrorCode ierr; 719 720 PetscFunctionBegin; 721 PetscValidLogicalCollectiveReal(ts,tol,2); 722 ierr = PetscTryMethod(ts,"TSSundialsSetLinearTolerance_C",(TS,double),(ts,tol));CHKERRQ(ierr); 723 PetscFunctionReturn(0); 724 } 725 726 /*@ 727 TSSundialsSetGramSchmidtType - Sets type of orthogonalization used 728 in GMRES method by SUNDIALS linear solver. 729 730 Logically Collective on TS 731 732 Input parameters: 733 + ts - the time-step context 734 - type - either SUNDIALS_MODIFIED_GS or SUNDIALS_CLASSICAL_GS 735 736 Level: advanced 737 738 .seealso: TSSundialsGetIterations(), TSSundialsSetType(), TSSundialsSetMaxl(), 739 TSSundialsSetLinearTolerance(), TSSundialsSetTolerance(), 740 TSSundialsGetIterations(), TSSundialsSetType(), 741 TSSundialsSetLinearTolerance(), TSSundialsSetTolerance(), TSSundialsGetPC(), 742 TSSetExactFinalTime() 743 744 @*/ 745 PetscErrorCode TSSundialsSetGramSchmidtType(TS ts,TSSundialsGramSchmidtType type) 746 { 747 PetscErrorCode ierr; 748 749 PetscFunctionBegin; 750 ierr = PetscTryMethod(ts,"TSSundialsSetGramSchmidtType_C",(TS,TSSundialsGramSchmidtType),(ts,type));CHKERRQ(ierr); 751 PetscFunctionReturn(0); 752 } 753 754 /*@ 755 TSSundialsSetTolerance - Sets the absolute and relative tolerance used by 756 Sundials for error control. 757 758 Logically Collective on TS 759 760 Input parameters: 761 + ts - the time-step context 762 . aabs - the absolute tolerance 763 - rel - the relative tolerance 764 765 See the Cvode/Sundials users manual for exact details on these parameters. Essentially 766 these regulate the size of the error for a SINGLE timestep. 767 768 Level: intermediate 769 770 .seealso: TSSundialsGetIterations(), TSSundialsSetType(), TSSundialsSetGMRESMaxl(), 771 TSSundialsSetLinearTolerance(), TSSundialsSetGramSchmidtType(), 772 TSSundialsGetIterations(), TSSundialsSetType(), 773 TSSundialsSetLinearTolerance(), TSSundialsSetTolerance(), TSSundialsGetPC(), 774 TSSetExactFinalTime() 775 776 @*/ 777 PetscErrorCode TSSundialsSetTolerance(TS ts,double aabs,double rel) 778 { 779 PetscErrorCode ierr; 780 781 PetscFunctionBegin; 782 ierr = PetscTryMethod(ts,"TSSundialsSetTolerance_C",(TS,double,double),(ts,aabs,rel));CHKERRQ(ierr); 783 PetscFunctionReturn(0); 784 } 785 786 /*@ 787 TSSundialsGetPC - Extract the PC context from a time-step context for Sundials. 788 789 Input Parameter: 790 . ts - the time-step context 791 792 Output Parameter: 793 . pc - the preconditioner context 794 795 Level: advanced 796 797 .seealso: TSSundialsGetIterations(), TSSundialsSetType(), TSSundialsSetMaxl(), 798 TSSundialsSetLinearTolerance(), TSSundialsSetGramSchmidtType(), TSSundialsSetTolerance(), 799 TSSundialsGetIterations(), TSSundialsSetType(), 800 TSSundialsSetLinearTolerance(), TSSundialsSetTolerance() 801 @*/ 802 PetscErrorCode TSSundialsGetPC(TS ts,PC *pc) 803 { 804 PetscErrorCode ierr; 805 806 PetscFunctionBegin; 807 ierr = PetscUseMethod(ts,"TSSundialsGetPC_C",(TS,PC*),(ts,pc));CHKERRQ(ierr); 808 PetscFunctionReturn(0); 809 } 810 811 /*@ 812 TSSundialsSetMinTimeStep - Smallest time step to be chosen by the adaptive controller. 813 814 Input Parameter: 815 + ts - the time-step context 816 - mindt - lowest time step if positive, negative to deactivate 817 818 Note: 819 Sundials will error if it is not possible to keep the estimated truncation error below 820 the tolerance set with TSSundialsSetTolerance() without going below this step size. 821 822 Level: beginner 823 824 .seealso: TSSundialsSetType(), TSSundialsSetTolerance(), 825 @*/ 826 PetscErrorCode TSSundialsSetMinTimeStep(TS ts,PetscReal mindt) 827 { 828 PetscErrorCode ierr; 829 830 PetscFunctionBegin; 831 ierr = PetscTryMethod(ts,"TSSundialsSetMinTimeStep_C",(TS,PetscReal),(ts,mindt));CHKERRQ(ierr); 832 PetscFunctionReturn(0); 833 } 834 835 /*@ 836 TSSundialsSetMaxTimeStep - Largest time step to be chosen by the adaptive controller. 837 838 Input Parameter: 839 + ts - the time-step context 840 - maxdt - lowest time step if positive, negative to deactivate 841 842 Level: beginner 843 844 .seealso: TSSundialsSetType(), TSSundialsSetTolerance(), 845 @*/ 846 PetscErrorCode TSSundialsSetMaxTimeStep(TS ts,PetscReal maxdt) 847 { 848 PetscErrorCode ierr; 849 850 PetscFunctionBegin; 851 ierr = PetscTryMethod(ts,"TSSundialsSetMaxTimeStep_C",(TS,PetscReal),(ts,maxdt));CHKERRQ(ierr); 852 PetscFunctionReturn(0); 853 } 854 855 /*@ 856 TSSundialsMonitorInternalSteps - Monitor Sundials internal steps (Defaults to false). 857 858 Input Parameter: 859 + ts - the time-step context 860 - ft - PETSC_TRUE if monitor, else PETSC_FALSE 861 862 Level: beginner 863 864 .seealso:TSSundialsGetIterations(), TSSundialsSetType(), TSSundialsSetMaxl(), 865 TSSundialsSetLinearTolerance(), TSSundialsSetGramSchmidtType(), TSSundialsSetTolerance(), 866 TSSundialsGetIterations(), TSSundialsSetType(), 867 TSSundialsSetLinearTolerance(), TSSundialsSetTolerance(), TSSundialsGetPC() 868 @*/ 869 PetscErrorCode TSSundialsMonitorInternalSteps(TS ts,PetscBool ft) 870 { 871 PetscErrorCode ierr; 872 873 PetscFunctionBegin; 874 ierr = PetscTryMethod(ts,"TSSundialsMonitorInternalSteps_C",(TS,PetscBool),(ts,ft));CHKERRQ(ierr); 875 PetscFunctionReturn(0); 876 } 877 /* -------------------------------------------------------------------------------------------*/ 878 /*MC 879 TSSUNDIALS - ODE solver using the LLNL CVODE/SUNDIALS package (now called SUNDIALS) 880 881 Options Database: 882 + -ts_sundials_type <bdf,adams> - 883 . -ts_sundials_gramschmidt_type <modified, classical> - type of orthogonalization inside GMRES 884 . -ts_sundials_atol <tol> - Absolute tolerance for convergence 885 . -ts_sundials_rtol <tol> - Relative tolerance for convergence 886 . -ts_sundials_linear_tolerance <tol> - 887 . -ts_sundials_maxl <maxl> - Max dimension of the Krylov subspace 888 - -ts_sundials_monitor_steps - Monitor SUNDIALS internal steps 889 890 891 Notes: 892 This uses its own nonlinear solver and Krylov method so PETSc SNES and KSP options do not apply, 893 only PETSc PC options. 894 895 Level: beginner 896 897 .seealso: TSCreate(), TS, TSSetType(), TSSundialsSetType(), TSSundialsSetMaxl(), TSSundialsSetLinearTolerance(), 898 TSSundialsSetGramSchmidtType(), TSSundialsSetTolerance(), TSSundialsGetPC(), TSSundialsGetIterations(), TSSetExactFinalTime() 899 900 M*/ 901 PETSC_EXTERN PetscErrorCode TSCreate_Sundials(TS ts) 902 { 903 TS_Sundials *cvode; 904 PetscErrorCode ierr; 905 PC pc; 906 907 PetscFunctionBegin; 908 ts->ops->reset = TSReset_Sundials; 909 ts->ops->destroy = TSDestroy_Sundials; 910 ts->ops->view = TSView_Sundials; 911 ts->ops->setup = TSSetUp_Sundials; 912 ts->ops->step = TSStep_Sundials; 913 ts->ops->interpolate = TSInterpolate_Sundials; 914 ts->ops->setfromoptions = TSSetFromOptions_Sundials; 915 ts->default_adapt_type = TSADAPTNONE; 916 917 ierr = PetscNewLog(ts,&cvode);CHKERRQ(ierr); 918 919 ts->usessnes = PETSC_TRUE; 920 921 ts->data = (void*)cvode; 922 cvode->cvode_type = SUNDIALS_BDF; 923 cvode->gtype = SUNDIALS_CLASSICAL_GS; 924 cvode->maxl = 5; 925 cvode->maxord = PETSC_DEFAULT; 926 cvode->linear_tol = .05; 927 cvode->monitorstep = PETSC_TRUE; 928 929 ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)ts),&(cvode->comm_sundials));CHKERRQ(ierr); 930 931 cvode->mindt = -1.; 932 cvode->maxdt = -1.; 933 934 /* set tolerance for Sundials */ 935 cvode->reltol = 1e-6; 936 cvode->abstol = 1e-6; 937 938 /* set PCNONE as default pctype */ 939 ierr = TSSundialsGetPC_Sundials(ts,&pc);CHKERRQ(ierr); 940 ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr); 941 942 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSundialsSetType_C",TSSundialsSetType_Sundials);CHKERRQ(ierr); 943 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSundialsSetMaxl_C",TSSundialsSetMaxl_Sundials);CHKERRQ(ierr); 944 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSundialsSetLinearTolerance_C",TSSundialsSetLinearTolerance_Sundials);CHKERRQ(ierr); 945 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSundialsSetGramSchmidtType_C",TSSundialsSetGramSchmidtType_Sundials);CHKERRQ(ierr); 946 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSundialsSetTolerance_C",TSSundialsSetTolerance_Sundials);CHKERRQ(ierr); 947 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSundialsSetMinTimeStep_C",TSSundialsSetMinTimeStep_Sundials);CHKERRQ(ierr); 948 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSundialsSetMaxTimeStep_C",TSSundialsSetMaxTimeStep_Sundials);CHKERRQ(ierr); 949 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSundialsGetPC_C",TSSundialsGetPC_Sundials);CHKERRQ(ierr); 950 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSundialsGetIterations_C",TSSundialsGetIterations_Sundials);CHKERRQ(ierr); 951 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSundialsMonitorInternalSteps_C",TSSundialsMonitorInternalSteps_Sundials);CHKERRQ(ierr); 952 PetscFunctionReturn(0); 953 } 954