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