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