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));CHKERRMPI(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,NULL,&cvode->w1);CHKERRQ(ierr); 304 ierr = VecCreateMPIWithArray(PetscObjectComm((PetscObject)ts),1,locsize,PETSC_DECIDE,NULL,&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 initial 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_",NULL}; 378 /* type of G-S orthogonalization used by CVODE linear solver */ 379 const char *const TSSundialsGramSchmidtTypes[] = {"","MODIFIED","CLASSICAL","TSSundialsGramSchmidtType","SUNDIALS_",NULL}; 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 PetscErrorCode TSSundialsSetType_Sundials(TS ts,TSSundialsLmmType type) 486 { 487 TS_Sundials *cvode = (TS_Sundials*)ts->data; 488 489 PetscFunctionBegin; 490 cvode->cvode_type = type; 491 PetscFunctionReturn(0); 492 } 493 494 PetscErrorCode TSSundialsSetMaxl_Sundials(TS ts,PetscInt maxl) 495 { 496 TS_Sundials *cvode = (TS_Sundials*)ts->data; 497 498 PetscFunctionBegin; 499 cvode->maxl = maxl; 500 PetscFunctionReturn(0); 501 } 502 503 PetscErrorCode TSSundialsSetLinearTolerance_Sundials(TS ts,double tol) 504 { 505 TS_Sundials *cvode = (TS_Sundials*)ts->data; 506 507 PetscFunctionBegin; 508 cvode->linear_tol = tol; 509 PetscFunctionReturn(0); 510 } 511 512 PetscErrorCode TSSundialsSetGramSchmidtType_Sundials(TS ts,TSSundialsGramSchmidtType type) 513 { 514 TS_Sundials *cvode = (TS_Sundials*)ts->data; 515 516 PetscFunctionBegin; 517 cvode->gtype = type; 518 PetscFunctionReturn(0); 519 } 520 521 PetscErrorCode TSSundialsSetTolerance_Sundials(TS ts,double aabs,double rel) 522 { 523 TS_Sundials *cvode = (TS_Sundials*)ts->data; 524 525 PetscFunctionBegin; 526 if (aabs != PETSC_DECIDE) cvode->abstol = aabs; 527 if (rel != PETSC_DECIDE) cvode->reltol = rel; 528 PetscFunctionReturn(0); 529 } 530 531 PetscErrorCode TSSundialsSetMinTimeStep_Sundials(TS ts,PetscReal mindt) 532 { 533 TS_Sundials *cvode = (TS_Sundials*)ts->data; 534 535 PetscFunctionBegin; 536 cvode->mindt = mindt; 537 PetscFunctionReturn(0); 538 } 539 540 PetscErrorCode TSSundialsSetMaxTimeStep_Sundials(TS ts,PetscReal maxdt) 541 { 542 TS_Sundials *cvode = (TS_Sundials*)ts->data; 543 544 PetscFunctionBegin; 545 cvode->maxdt = maxdt; 546 PetscFunctionReturn(0); 547 } 548 PetscErrorCode TSSundialsGetPC_Sundials(TS ts,PC *pc) 549 { 550 SNES snes; 551 KSP ksp; 552 PetscErrorCode ierr; 553 554 PetscFunctionBegin; 555 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 556 ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 557 ierr = KSPGetPC(ksp,pc);CHKERRQ(ierr); 558 PetscFunctionReturn(0); 559 } 560 561 PetscErrorCode TSSundialsGetIterations_Sundials(TS ts,int *nonlin,int *lin) 562 { 563 PetscFunctionBegin; 564 if (nonlin) *nonlin = ts->snes_its; 565 if (lin) *lin = ts->ksp_its; 566 PetscFunctionReturn(0); 567 } 568 569 PetscErrorCode TSSundialsMonitorInternalSteps_Sundials(TS ts,PetscBool s) 570 { 571 TS_Sundials *cvode = (TS_Sundials*)ts->data; 572 573 PetscFunctionBegin; 574 cvode->monitorstep = s; 575 PetscFunctionReturn(0); 576 } 577 /* -------------------------------------------------------------------------------------------*/ 578 579 /*@C 580 TSSundialsGetIterations - Gets the number of nonlinear and linear iterations used so far by Sundials. 581 582 Not Collective 583 584 Input Parameter: 585 . ts - the time-step context 586 587 Output Parameters: 588 + nonlin - number of nonlinear iterations 589 - lin - number of linear iterations 590 591 Level: advanced 592 593 Notes: 594 These return the number since the creation of the TS object 595 596 .seealso: TSSundialsSetType(), TSSundialsSetMaxl(), 597 TSSundialsSetLinearTolerance(), TSSundialsSetGramSchmidtType(), TSSundialsSetTolerance(), 598 TSSundialsGetIterations(), TSSundialsSetType(), 599 TSSundialsSetLinearTolerance(), TSSundialsGetPC(), TSSetExactFinalTime() 600 601 @*/ 602 PetscErrorCode TSSundialsGetIterations(TS ts,int *nonlin,int *lin) 603 { 604 PetscErrorCode ierr; 605 606 PetscFunctionBegin; 607 ierr = PetscUseMethod(ts,"TSSundialsGetIterations_C",(TS,int*,int*),(ts,nonlin,lin));CHKERRQ(ierr); 608 PetscFunctionReturn(0); 609 } 610 611 /*@ 612 TSSundialsSetType - Sets the method that Sundials will use for integration. 613 614 Logically Collective on TS 615 616 Input parameters: 617 + ts - the time-step context 618 - type - one of SUNDIALS_ADAMS or SUNDIALS_BDF 619 620 Level: intermediate 621 622 .seealso: TSSundialsGetIterations(), TSSundialsSetMaxl(), 623 TSSundialsSetLinearTolerance(), TSSundialsSetGramSchmidtType(), TSSundialsSetTolerance(), 624 TSSundialsGetIterations(), TSSundialsSetType(), 625 TSSundialsSetLinearTolerance(), TSSundialsSetTolerance(), TSSundialsGetPC(), 626 TSSetExactFinalTime() 627 @*/ 628 PetscErrorCode TSSundialsSetType(TS ts,TSSundialsLmmType type) 629 { 630 PetscErrorCode ierr; 631 632 PetscFunctionBegin; 633 ierr = PetscTryMethod(ts,"TSSundialsSetType_C",(TS,TSSundialsLmmType),(ts,type));CHKERRQ(ierr); 634 PetscFunctionReturn(0); 635 } 636 637 /*@ 638 TSSundialsSetMaxord - Sets the maximum order for BDF/Adams method used by SUNDIALS. 639 640 Logically Collective on TS 641 642 Input parameters: 643 + ts - the time-step context 644 - maxord - maximum order of BDF / Adams method 645 646 Level: advanced 647 648 .seealso: TSSundialsGetIterations(), TSSundialsSetType(), 649 TSSundialsSetLinearTolerance(), TSSundialsSetGramSchmidtType(), TSSundialsSetTolerance(), 650 TSSundialsGetIterations(), TSSundialsSetType(), 651 TSSundialsSetLinearTolerance(), TSSundialsSetTolerance(), TSSundialsGetPC(), 652 TSSetExactFinalTime() 653 654 @*/ 655 PetscErrorCode TSSundialsSetMaxord(TS ts,PetscInt maxord) 656 { 657 PetscErrorCode ierr; 658 659 PetscFunctionBegin; 660 PetscValidLogicalCollectiveInt(ts,maxord,2); 661 ierr = PetscTryMethod(ts,"TSSundialsSetMaxOrd_C",(TS,PetscInt),(ts,maxord));CHKERRQ(ierr); 662 PetscFunctionReturn(0); 663 } 664 665 /*@ 666 TSSundialsSetMaxl - Sets the dimension of the Krylov space used by 667 GMRES in the linear solver in SUNDIALS. SUNDIALS DOES NOT use restarted GMRES so 668 this is the maximum number of GMRES steps that will be used. 669 670 Logically Collective on TS 671 672 Input parameters: 673 + ts - the time-step context 674 - maxl - number of direction vectors (the dimension of Krylov subspace). 675 676 Level: advanced 677 678 .seealso: TSSundialsGetIterations(), TSSundialsSetType(), 679 TSSundialsSetLinearTolerance(), TSSundialsSetGramSchmidtType(), TSSundialsSetTolerance(), 680 TSSundialsGetIterations(), TSSundialsSetType(), 681 TSSundialsSetLinearTolerance(), TSSundialsSetTolerance(), TSSundialsGetPC(), 682 TSSetExactFinalTime() 683 684 @*/ 685 PetscErrorCode TSSundialsSetMaxl(TS ts,PetscInt maxl) 686 { 687 PetscErrorCode ierr; 688 689 PetscFunctionBegin; 690 PetscValidLogicalCollectiveInt(ts,maxl,2); 691 ierr = PetscTryMethod(ts,"TSSundialsSetMaxl_C",(TS,PetscInt),(ts,maxl));CHKERRQ(ierr); 692 PetscFunctionReturn(0); 693 } 694 695 /*@ 696 TSSundialsSetLinearTolerance - Sets the tolerance used to solve the linear 697 system by SUNDIALS. 698 699 Logically Collective on TS 700 701 Input parameters: 702 + ts - the time-step context 703 - tol - the factor by which the tolerance on the nonlinear solver is 704 multiplied to get the tolerance on the linear solver, .05 by default. 705 706 Level: advanced 707 708 .seealso: TSSundialsGetIterations(), TSSundialsSetType(), TSSundialsSetMaxl(), 709 TSSundialsSetGramSchmidtType(), TSSundialsSetTolerance(), 710 TSSundialsGetIterations(), TSSundialsSetType(), 711 TSSundialsSetLinearTolerance(), TSSundialsSetTolerance(), TSSundialsGetPC(), 712 TSSetExactFinalTime() 713 714 @*/ 715 PetscErrorCode TSSundialsSetLinearTolerance(TS ts,double tol) 716 { 717 PetscErrorCode ierr; 718 719 PetscFunctionBegin; 720 PetscValidLogicalCollectiveReal(ts,tol,2); 721 ierr = PetscTryMethod(ts,"TSSundialsSetLinearTolerance_C",(TS,double),(ts,tol));CHKERRQ(ierr); 722 PetscFunctionReturn(0); 723 } 724 725 /*@ 726 TSSundialsSetGramSchmidtType - Sets type of orthogonalization used 727 in GMRES method by SUNDIALS linear solver. 728 729 Logically Collective on TS 730 731 Input parameters: 732 + ts - the time-step context 733 - type - either SUNDIALS_MODIFIED_GS or SUNDIALS_CLASSICAL_GS 734 735 Level: advanced 736 737 .seealso: TSSundialsGetIterations(), TSSundialsSetType(), TSSundialsSetMaxl(), 738 TSSundialsSetLinearTolerance(), TSSundialsSetTolerance(), 739 TSSundialsGetIterations(), TSSundialsSetType(), 740 TSSundialsSetLinearTolerance(), TSSundialsSetTolerance(), TSSundialsGetPC(), 741 TSSetExactFinalTime() 742 743 @*/ 744 PetscErrorCode TSSundialsSetGramSchmidtType(TS ts,TSSundialsGramSchmidtType type) 745 { 746 PetscErrorCode ierr; 747 748 PetscFunctionBegin; 749 ierr = PetscTryMethod(ts,"TSSundialsSetGramSchmidtType_C",(TS,TSSundialsGramSchmidtType),(ts,type));CHKERRQ(ierr); 750 PetscFunctionReturn(0); 751 } 752 753 /*@ 754 TSSundialsSetTolerance - Sets the absolute and relative tolerance used by 755 Sundials for error control. 756 757 Logically Collective on TS 758 759 Input parameters: 760 + ts - the time-step context 761 . aabs - the absolute tolerance 762 - rel - the relative tolerance 763 764 See the Cvode/Sundials users manual for exact details on these parameters. Essentially 765 these regulate the size of the error for a SINGLE timestep. 766 767 Level: intermediate 768 769 .seealso: TSSundialsGetIterations(), TSSundialsSetType(), TSSundialsSetGMRESMaxl(), 770 TSSundialsSetLinearTolerance(), TSSundialsSetGramSchmidtType(), 771 TSSundialsGetIterations(), TSSundialsSetType(), 772 TSSundialsSetLinearTolerance(), TSSundialsSetTolerance(), TSSundialsGetPC(), 773 TSSetExactFinalTime() 774 775 @*/ 776 PetscErrorCode TSSundialsSetTolerance(TS ts,double aabs,double rel) 777 { 778 PetscErrorCode ierr; 779 780 PetscFunctionBegin; 781 ierr = PetscTryMethod(ts,"TSSundialsSetTolerance_C",(TS,double,double),(ts,aabs,rel));CHKERRQ(ierr); 782 PetscFunctionReturn(0); 783 } 784 785 /*@ 786 TSSundialsGetPC - Extract the PC context from a time-step context for Sundials. 787 788 Input Parameter: 789 . ts - the time-step context 790 791 Output Parameter: 792 . pc - the preconditioner context 793 794 Level: advanced 795 796 .seealso: TSSundialsGetIterations(), TSSundialsSetType(), TSSundialsSetMaxl(), 797 TSSundialsSetLinearTolerance(), TSSundialsSetGramSchmidtType(), TSSundialsSetTolerance(), 798 TSSundialsGetIterations(), TSSundialsSetType(), 799 TSSundialsSetLinearTolerance(), TSSundialsSetTolerance() 800 @*/ 801 PetscErrorCode TSSundialsGetPC(TS ts,PC *pc) 802 { 803 PetscErrorCode ierr; 804 805 PetscFunctionBegin; 806 ierr = PetscUseMethod(ts,"TSSundialsGetPC_C",(TS,PC*),(ts,pc));CHKERRQ(ierr); 807 PetscFunctionReturn(0); 808 } 809 810 /*@ 811 TSSundialsSetMinTimeStep - Smallest time step to be chosen by the adaptive controller. 812 813 Input Parameters: 814 + ts - the time-step context 815 - mindt - lowest time step if positive, negative to deactivate 816 817 Note: 818 Sundials will error if it is not possible to keep the estimated truncation error below 819 the tolerance set with TSSundialsSetTolerance() without going below this step size. 820 821 Level: beginner 822 823 .seealso: TSSundialsSetType(), TSSundialsSetTolerance(), 824 @*/ 825 PetscErrorCode TSSundialsSetMinTimeStep(TS ts,PetscReal mindt) 826 { 827 PetscErrorCode ierr; 828 829 PetscFunctionBegin; 830 ierr = PetscTryMethod(ts,"TSSundialsSetMinTimeStep_C",(TS,PetscReal),(ts,mindt));CHKERRQ(ierr); 831 PetscFunctionReturn(0); 832 } 833 834 /*@ 835 TSSundialsSetMaxTimeStep - Largest time step to be chosen by the adaptive controller. 836 837 Input Parameters: 838 + ts - the time-step context 839 - maxdt - lowest time step if positive, negative to deactivate 840 841 Level: beginner 842 843 .seealso: TSSundialsSetType(), TSSundialsSetTolerance(), 844 @*/ 845 PetscErrorCode TSSundialsSetMaxTimeStep(TS ts,PetscReal maxdt) 846 { 847 PetscErrorCode ierr; 848 849 PetscFunctionBegin; 850 ierr = PetscTryMethod(ts,"TSSundialsSetMaxTimeStep_C",(TS,PetscReal),(ts,maxdt));CHKERRQ(ierr); 851 PetscFunctionReturn(0); 852 } 853 854 /*@ 855 TSSundialsMonitorInternalSteps - Monitor Sundials internal steps (Defaults to false). 856 857 Input Parameters: 858 + ts - the time-step context 859 - ft - PETSC_TRUE if monitor, else PETSC_FALSE 860 861 Level: beginner 862 863 .seealso:TSSundialsGetIterations(), TSSundialsSetType(), TSSundialsSetMaxl(), 864 TSSundialsSetLinearTolerance(), TSSundialsSetGramSchmidtType(), TSSundialsSetTolerance(), 865 TSSundialsGetIterations(), TSSundialsSetType(), 866 TSSundialsSetLinearTolerance(), TSSundialsSetTolerance(), TSSundialsGetPC() 867 @*/ 868 PetscErrorCode TSSundialsMonitorInternalSteps(TS ts,PetscBool ft) 869 { 870 PetscErrorCode ierr; 871 872 PetscFunctionBegin; 873 ierr = PetscTryMethod(ts,"TSSundialsMonitorInternalSteps_C",(TS,PetscBool),(ts,ft));CHKERRQ(ierr); 874 PetscFunctionReturn(0); 875 } 876 /* -------------------------------------------------------------------------------------------*/ 877 /*MC 878 TSSUNDIALS - ODE solver using the LLNL CVODE/SUNDIALS package (now called SUNDIALS) 879 880 Options Database: 881 + -ts_sundials_type <bdf,adams> - 882 . -ts_sundials_gramschmidt_type <modified, classical> - type of orthogonalization inside GMRES 883 . -ts_sundials_atol <tol> - Absolute tolerance for convergence 884 . -ts_sundials_rtol <tol> - Relative tolerance for convergence 885 . -ts_sundials_linear_tolerance <tol> - 886 . -ts_sundials_maxl <maxl> - Max dimension of the Krylov subspace 887 - -ts_sundials_monitor_steps - Monitor SUNDIALS internal steps 888 889 Notes: 890 This uses its own nonlinear solver and Krylov method so PETSc SNES and KSP options do not apply, 891 only PETSc PC options. 892 893 Level: beginner 894 895 .seealso: TSCreate(), TS, TSSetType(), TSSundialsSetType(), TSSundialsSetMaxl(), TSSundialsSetLinearTolerance(), 896 TSSundialsSetGramSchmidtType(), TSSundialsSetTolerance(), TSSundialsGetPC(), TSSundialsGetIterations(), TSSetExactFinalTime() 897 898 M*/ 899 PETSC_EXTERN PetscErrorCode TSCreate_Sundials(TS ts) 900 { 901 TS_Sundials *cvode; 902 PetscErrorCode ierr; 903 PC pc; 904 905 PetscFunctionBegin; 906 ts->ops->reset = TSReset_Sundials; 907 ts->ops->destroy = TSDestroy_Sundials; 908 ts->ops->view = TSView_Sundials; 909 ts->ops->setup = TSSetUp_Sundials; 910 ts->ops->step = TSStep_Sundials; 911 ts->ops->interpolate = TSInterpolate_Sundials; 912 ts->ops->setfromoptions = TSSetFromOptions_Sundials; 913 ts->default_adapt_type = TSADAPTNONE; 914 915 ierr = PetscNewLog(ts,&cvode);CHKERRQ(ierr); 916 917 ts->usessnes = PETSC_TRUE; 918 919 ts->data = (void*)cvode; 920 cvode->cvode_type = SUNDIALS_BDF; 921 cvode->gtype = SUNDIALS_CLASSICAL_GS; 922 cvode->maxl = 5; 923 cvode->maxord = PETSC_DEFAULT; 924 cvode->linear_tol = .05; 925 cvode->monitorstep = PETSC_TRUE; 926 927 ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)ts),&(cvode->comm_sundials));CHKERRMPI(ierr); 928 929 cvode->mindt = -1.; 930 cvode->maxdt = -1.; 931 932 /* set tolerance for Sundials */ 933 cvode->reltol = 1e-6; 934 cvode->abstol = 1e-6; 935 936 /* set PCNONE as default pctype */ 937 ierr = TSSundialsGetPC_Sundials(ts,&pc);CHKERRQ(ierr); 938 ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr); 939 940 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSundialsSetType_C",TSSundialsSetType_Sundials);CHKERRQ(ierr); 941 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSundialsSetMaxl_C",TSSundialsSetMaxl_Sundials);CHKERRQ(ierr); 942 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSundialsSetLinearTolerance_C",TSSundialsSetLinearTolerance_Sundials);CHKERRQ(ierr); 943 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSundialsSetGramSchmidtType_C",TSSundialsSetGramSchmidtType_Sundials);CHKERRQ(ierr); 944 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSundialsSetTolerance_C",TSSundialsSetTolerance_Sundials);CHKERRQ(ierr); 945 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSundialsSetMinTimeStep_C",TSSundialsSetMinTimeStep_Sundials);CHKERRQ(ierr); 946 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSundialsSetMaxTimeStep_C",TSSundialsSetMaxTimeStep_Sundials);CHKERRQ(ierr); 947 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSundialsGetPC_C",TSSundialsGetPC_Sundials);CHKERRQ(ierr); 948 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSundialsGetIterations_C",TSSundialsGetIterations_Sundials);CHKERRQ(ierr); 949 ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSundialsMonitorInternalSteps_C",TSSundialsMonitorInternalSteps_Sundials);CHKERRQ(ierr); 950 PetscFunctionReturn(0); 951 } 952