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 = PetscMemcpy(y_data,parray,locsize*sizeof(PETSC_SCALAR)); CHKERRQ(ierr);*/ 287 ierr = VecRestoreArray(ts->vec_sol,PETSC_NULL);CHKERRQ(ierr); 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 422 PetscFunctionBegin; 423 if (cvode->cvode_type == SUNDIALS_ADAMS) {type = atype;} 424 else {type = btype;} 425 426 ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 427 ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); 428 if (iascii) { 429 ierr = PetscViewerASCIIPrintf(viewer,"Sundials integrater does not use SNES!\n");CHKERRQ(ierr); 430 ierr = PetscViewerASCIIPrintf(viewer,"Sundials integrater type %s\n",type);CHKERRQ(ierr); 431 ierr = PetscViewerASCIIPrintf(viewer,"Sundials abs tol %g rel tol %g\n",cvode->abstol,cvode->reltol);CHKERRQ(ierr); 432 ierr = PetscViewerASCIIPrintf(viewer,"Sundials linear solver tolerance factor %g\n",cvode->linear_tol);CHKERRQ(ierr); 433 ierr = PetscViewerASCIIPrintf(viewer,"Sundials GMRES max iterations (same as restart in SUNDIALS) %D\n",cvode->restart);CHKERRQ(ierr); 434 if (cvode->gtype == SUNDIALS_MODIFIED_GS) { 435 ierr = PetscViewerASCIIPrintf(viewer,"Sundials using modified Gram-Schmidt for orthogonalization in GMRES\n");CHKERRQ(ierr); 436 } else { 437 ierr = PetscViewerASCIIPrintf(viewer,"Sundials using unmodified (classical) Gram-Schmidt for orthogonalization in GMRES\n");CHKERRQ(ierr); 438 } 439 if (cvode->mindt > 0) {ierr = PetscViewerASCIIPrintf(viewer,"Sundials minimum time step %g\n",cvode->mindt);CHKERRQ(ierr);} 440 if (cvode->maxdt > 0) {ierr = PetscViewerASCIIPrintf(viewer,"Sundials maximum time step %g\n",cvode->maxdt);CHKERRQ(ierr);} 441 442 /* Outputs from CVODE, CVSPILS */ 443 ierr = CVodeGetTolScaleFactor(cvode->mem,&tolsfac);CHKERRQ(ierr); 444 ierr = PetscViewerASCIIPrintf(viewer,"Sundials suggested factor for tolerance scaling %g\n",tolsfac);CHKERRQ(ierr); 445 ierr = CVodeGetIntegratorStats(cvode->mem,&nsteps,&nfevals, 446 &nlinsetups,&nfails,&qlast,&qcur, 447 &hinused,&hlast,&hcur,&tcur);CHKERRQ(ierr); 448 ierr = PetscViewerASCIIPrintf(viewer,"Sundials cumulative number of internal steps %D\n",nsteps);CHKERRQ(ierr); 449 ierr = PetscViewerASCIIPrintf(viewer,"Sundials no. of calls to rhs function %D\n",nfevals);CHKERRQ(ierr); 450 ierr = PetscViewerASCIIPrintf(viewer,"Sundials no. of calls to linear solver setup function %D\n",nlinsetups);CHKERRQ(ierr); 451 ierr = PetscViewerASCIIPrintf(viewer,"Sundials no. of error test failures %D\n",nfails);CHKERRQ(ierr); 452 453 ierr = CVodeGetNonlinSolvStats(cvode->mem,&its,&nfails);CHKERRQ(ierr); 454 ierr = PetscViewerASCIIPrintf(viewer,"Sundials no. of nonlinear solver iterations %D\n",its);CHKERRQ(ierr); 455 ierr = PetscViewerASCIIPrintf(viewer,"Sundials no. of nonlinear convergence failure %D\n",nfails);CHKERRQ(ierr); 456 457 ierr = CVSpilsGetNumLinIters(cvode->mem, &its);CHKERRQ(ierr); /* its = no. of calls to TSPrecond_Sundials() */ 458 ierr = PetscViewerASCIIPrintf(viewer,"Sundials no. of linear iterations %D\n",its);CHKERRQ(ierr); 459 ierr = CVSpilsGetNumConvFails(cvode->mem,&itmp);CHKERRQ(ierr); 460 ierr = PetscViewerASCIIPrintf(viewer,"Sundials no. of linear convergence failures %D\n",itmp);CHKERRQ(ierr); 461 ierr = CVSpilsGetNumPrecEvals(cvode->mem,&itmp);CHKERRQ(ierr); 462 ierr = PetscViewerASCIIPrintf(viewer,"Sundials no. of preconditioner evaluations %D\n",itmp);CHKERRQ(ierr); 463 ierr = CVSpilsGetNumPrecSolves(cvode->mem,&itmp);CHKERRQ(ierr); 464 ierr = PetscViewerASCIIPrintf(viewer,"Sundials no. of preconditioner solves %D\n",itmp);CHKERRQ(ierr); 465 ierr = CVSpilsGetNumJtimesEvals(cvode->mem,&itmp);CHKERRQ(ierr); 466 ierr = PetscViewerASCIIPrintf(viewer,"Sundials no. of Jacobian-vector product evaluations %D\n",itmp);CHKERRQ(ierr); 467 ierr = CVSpilsGetNumRhsEvals(cvode->mem,&itmp);CHKERRQ(ierr); 468 ierr = PetscViewerASCIIPrintf(viewer,"Sundials no. of rhs calls for finite diff. Jacobian-vector evals %D\n",itmp);CHKERRQ(ierr); 469 } else if (isstring) { 470 ierr = PetscViewerStringSPrintf(viewer,"Sundials type %s",type);CHKERRQ(ierr); 471 } else { 472 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Viewer type %s not supported by TS Sundials",((PetscObject)viewer)->type_name); 473 } 474 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 475 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 476 PetscFunctionReturn(0); 477 } 478 479 480 /* --------------------------------------------------------------------------*/ 481 EXTERN_C_BEGIN 482 #undef __FUNCT__ 483 #define __FUNCT__ "TSSundialsSetType_Sundials" 484 PetscErrorCode TSSundialsSetType_Sundials(TS ts,TSSundialsLmmType type) 485 { 486 TS_Sundials *cvode = (TS_Sundials*)ts->data; 487 488 PetscFunctionBegin; 489 cvode->cvode_type = type; 490 PetscFunctionReturn(0); 491 } 492 EXTERN_C_END 493 494 EXTERN_C_BEGIN 495 #undef __FUNCT__ 496 #define __FUNCT__ "TSSundialsSetGMRESRestart_Sundials" 497 PetscErrorCode TSSundialsSetGMRESRestart_Sundials(TS ts,int restart) 498 { 499 TS_Sundials *cvode = (TS_Sundials*)ts->data; 500 501 PetscFunctionBegin; 502 cvode->restart = restart; 503 PetscFunctionReturn(0); 504 } 505 EXTERN_C_END 506 507 EXTERN_C_BEGIN 508 #undef __FUNCT__ 509 #define __FUNCT__ "TSSundialsSetLinearTolerance_Sundials" 510 PetscErrorCode TSSundialsSetLinearTolerance_Sundials(TS ts,double tol) 511 { 512 TS_Sundials *cvode = (TS_Sundials*)ts->data; 513 514 PetscFunctionBegin; 515 cvode->linear_tol = tol; 516 PetscFunctionReturn(0); 517 } 518 EXTERN_C_END 519 520 EXTERN_C_BEGIN 521 #undef __FUNCT__ 522 #define __FUNCT__ "TSSundialsSetGramSchmidtType_Sundials" 523 PetscErrorCode TSSundialsSetGramSchmidtType_Sundials(TS ts,TSSundialsGramSchmidtType type) 524 { 525 TS_Sundials *cvode = (TS_Sundials*)ts->data; 526 527 PetscFunctionBegin; 528 cvode->gtype = type; 529 PetscFunctionReturn(0); 530 } 531 EXTERN_C_END 532 533 EXTERN_C_BEGIN 534 #undef __FUNCT__ 535 #define __FUNCT__ "TSSundialsSetTolerance_Sundials" 536 PetscErrorCode TSSundialsSetTolerance_Sundials(TS ts,double aabs,double rel) 537 { 538 TS_Sundials *cvode = (TS_Sundials*)ts->data; 539 540 PetscFunctionBegin; 541 if (aabs != PETSC_DECIDE) cvode->abstol = aabs; 542 if (rel != PETSC_DECIDE) cvode->reltol = rel; 543 PetscFunctionReturn(0); 544 } 545 EXTERN_C_END 546 547 EXTERN_C_BEGIN 548 #undef __FUNCT__ 549 #define __FUNCT__ "TSSundialsSetMinTimeStep_Sundials" 550 PetscErrorCode TSSundialsSetMinTimeStep_Sundials(TS ts,PetscReal mindt) 551 { 552 TS_Sundials *cvode = (TS_Sundials*)ts->data; 553 554 PetscFunctionBegin; 555 cvode->mindt = mindt; 556 PetscFunctionReturn(0); 557 } 558 EXTERN_C_END 559 560 EXTERN_C_BEGIN 561 #undef __FUNCT__ 562 #define __FUNCT__ "TSSundialsSetMaxTimeStep_Sundials" 563 PetscErrorCode TSSundialsSetMaxTimeStep_Sundials(TS ts,PetscReal maxdt) 564 { 565 TS_Sundials *cvode = (TS_Sundials*)ts->data; 566 567 PetscFunctionBegin; 568 cvode->maxdt = maxdt; 569 PetscFunctionReturn(0); 570 } 571 EXTERN_C_END 572 573 EXTERN_C_BEGIN 574 #undef __FUNCT__ 575 #define __FUNCT__ "TSSundialsGetPC_Sundials" 576 PetscErrorCode TSSundialsGetPC_Sundials(TS ts,PC *pc) 577 { 578 SNES snes; 579 KSP ksp; 580 PetscErrorCode ierr; 581 582 PetscFunctionBegin; 583 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 584 ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 585 ierr = KSPGetPC(ksp,pc); CHKERRQ(ierr); 586 PetscFunctionReturn(0); 587 } 588 EXTERN_C_END 589 590 EXTERN_C_BEGIN 591 #undef __FUNCT__ 592 #define __FUNCT__ "TSSundialsGetIterations_Sundials" 593 PetscErrorCode TSSundialsGetIterations_Sundials(TS ts,int *nonlin,int *lin) 594 { 595 PetscFunctionBegin; 596 if (nonlin) *nonlin = ts->nonlinear_its; 597 if (lin) *lin = ts->linear_its; 598 PetscFunctionReturn(0); 599 } 600 EXTERN_C_END 601 602 EXTERN_C_BEGIN 603 #undef __FUNCT__ 604 #define __FUNCT__ "TSSundialsSetExactFinalTime_Sundials" 605 PetscErrorCode TSSundialsSetExactFinalTime_Sundials(TS ts,PetscBool s) 606 { 607 TS_Sundials *cvode = (TS_Sundials*)ts->data; 608 609 PetscFunctionBegin; 610 cvode->exact_final_time = s; 611 PetscFunctionReturn(0); 612 } 613 EXTERN_C_END 614 615 EXTERN_C_BEGIN 616 #undef __FUNCT__ 617 #define __FUNCT__ "TSSundialsMonitorInternalSteps_Sundials" 618 PetscErrorCode TSSundialsMonitorInternalSteps_Sundials(TS ts,PetscBool s) 619 { 620 TS_Sundials *cvode = (TS_Sundials*)ts->data; 621 622 PetscFunctionBegin; 623 cvode->monitorstep = s; 624 PetscFunctionReturn(0); 625 } 626 EXTERN_C_END 627 /* -------------------------------------------------------------------------------------------*/ 628 629 #undef __FUNCT__ 630 #define __FUNCT__ "TSSundialsGetIterations" 631 /*@C 632 TSSundialsGetIterations - Gets the number of nonlinear and linear iterations used so far by Sundials. 633 634 Not Collective 635 636 Input parameters: 637 . ts - the time-step context 638 639 Output Parameters: 640 + nonlin - number of nonlinear iterations 641 - lin - number of linear iterations 642 643 Level: advanced 644 645 Notes: 646 These return the number since the creation of the TS object 647 648 .keywords: non-linear iterations, linear iterations 649 650 .seealso: TSSundialsSetType(), TSSundialsSetGMRESRestart(), 651 TSSundialsSetLinearTolerance(), TSSundialsSetGramSchmidtType(), TSSundialsSetTolerance(), 652 TSSundialsGetIterations(), TSSundialsSetType(), TSSundialsSetGMRESRestart(), 653 TSSundialsSetLinearTolerance(), TSSundialsGetPC(), TSSundialsSetExactFinalTime() 654 655 @*/ 656 PetscErrorCode TSSundialsGetIterations(TS ts,int *nonlin,int *lin) 657 { 658 PetscErrorCode ierr; 659 660 PetscFunctionBegin; 661 ierr = PetscUseMethod(ts,"TSSundialsGetIterations_C",(TS,int*,int*),(ts,nonlin,lin));CHKERRQ(ierr); 662 PetscFunctionReturn(0); 663 } 664 665 #undef __FUNCT__ 666 #define __FUNCT__ "TSSundialsSetType" 667 /*@ 668 TSSundialsSetType - Sets the method that Sundials will use for integration. 669 670 Logically Collective on TS 671 672 Input parameters: 673 + ts - the time-step context 674 - type - one of SUNDIALS_ADAMS or SUNDIALS_BDF 675 676 Level: intermediate 677 678 .keywords: Adams, backward differentiation formula 679 680 .seealso: TSSundialsGetIterations(), TSSundialsSetGMRESRestart(), 681 TSSundialsSetLinearTolerance(), TSSundialsSetGramSchmidtType(), TSSundialsSetTolerance(), 682 TSSundialsGetIterations(), TSSundialsSetType(), TSSundialsSetGMRESRestart(), 683 TSSundialsSetLinearTolerance(), TSSundialsSetTolerance(), TSSundialsGetPC(), 684 TSSundialsSetExactFinalTime() 685 @*/ 686 PetscErrorCode TSSundialsSetType(TS ts,TSSundialsLmmType type) 687 { 688 PetscErrorCode ierr; 689 690 PetscFunctionBegin; 691 ierr = PetscTryMethod(ts,"TSSundialsSetType_C",(TS,TSSundialsLmmType),(ts,type));CHKERRQ(ierr); 692 PetscFunctionReturn(0); 693 } 694 695 #undef __FUNCT__ 696 #define __FUNCT__ "TSSundialsSetGMRESRestart" 697 /*@ 698 TSSundialsSetGMRESRestart - Sets the dimension of the Krylov space used by 699 GMRES in the linear solver in SUNDIALS. SUNDIALS DOES NOT use restarted GMRES so 700 this is ALSO the maximum number of GMRES steps that will be used. 701 702 Logically Collective on TS 703 704 Input parameters: 705 + ts - the time-step context 706 - restart - number of direction vectors (the restart size). 707 708 Level: advanced 709 710 .keywords: GMRES, restart 711 712 .seealso: TSSundialsGetIterations(), TSSundialsSetType(), 713 TSSundialsSetLinearTolerance(), TSSundialsSetGramSchmidtType(), TSSundialsSetTolerance(), 714 TSSundialsGetIterations(), TSSundialsSetType(), TSSundialsSetGMRESRestart(), 715 TSSundialsSetLinearTolerance(), TSSundialsSetTolerance(), TSSundialsGetPC(), 716 TSSundialsSetExactFinalTime() 717 718 @*/ 719 PetscErrorCode TSSundialsSetGMRESRestart(TS ts,int restart) 720 { 721 PetscErrorCode ierr; 722 723 PetscFunctionBegin; 724 PetscValidLogicalCollectiveInt(ts,restart,2); 725 ierr = PetscTryMethod(ts,"TSSundialsSetGMRESRestart_C",(TS,int),(ts,restart));CHKERRQ(ierr); 726 PetscFunctionReturn(0); 727 } 728 729 #undef __FUNCT__ 730 #define __FUNCT__ "TSSundialsSetLinearTolerance" 731 /*@ 732 TSSundialsSetLinearTolerance - Sets the tolerance used to solve the linear 733 system by SUNDIALS. 734 735 Logically Collective on TS 736 737 Input parameters: 738 + ts - the time-step context 739 - tol - the factor by which the tolerance on the nonlinear solver is 740 multiplied to get the tolerance on the linear solver, .05 by default. 741 742 Level: advanced 743 744 .keywords: GMRES, linear convergence tolerance, SUNDIALS 745 746 .seealso: TSSundialsGetIterations(), TSSundialsSetType(), TSSundialsSetGMRESRestart(), 747 TSSundialsSetGramSchmidtType(), TSSundialsSetTolerance(), 748 TSSundialsGetIterations(), TSSundialsSetType(), TSSundialsSetGMRESRestart(), 749 TSSundialsSetLinearTolerance(), TSSundialsSetTolerance(), TSSundialsGetPC(), 750 TSSundialsSetExactFinalTime() 751 752 @*/ 753 PetscErrorCode TSSundialsSetLinearTolerance(TS ts,double tol) 754 { 755 PetscErrorCode ierr; 756 757 PetscFunctionBegin; 758 PetscValidLogicalCollectiveReal(ts,tol,2); 759 ierr = PetscTryMethod(ts,"TSSundialsSetLinearTolerance_C",(TS,double),(ts,tol));CHKERRQ(ierr); 760 PetscFunctionReturn(0); 761 } 762 763 #undef __FUNCT__ 764 #define __FUNCT__ "TSSundialsSetGramSchmidtType" 765 /*@ 766 TSSundialsSetGramSchmidtType - Sets type of orthogonalization used 767 in GMRES method by SUNDIALS linear solver. 768 769 Logically Collective on TS 770 771 Input parameters: 772 + ts - the time-step context 773 - type - either SUNDIALS_MODIFIED_GS or SUNDIALS_CLASSICAL_GS 774 775 Level: advanced 776 777 .keywords: Sundials, orthogonalization 778 779 .seealso: TSSundialsGetIterations(), TSSundialsSetType(), TSSundialsSetGMRESRestart(), 780 TSSundialsSetLinearTolerance(), TSSundialsSetTolerance(), 781 TSSundialsGetIterations(), TSSundialsSetType(), TSSundialsSetGMRESRestart(), 782 TSSundialsSetLinearTolerance(), TSSundialsSetTolerance(), TSSundialsGetPC(), 783 TSSundialsSetExactFinalTime() 784 785 @*/ 786 PetscErrorCode TSSundialsSetGramSchmidtType(TS ts,TSSundialsGramSchmidtType type) 787 { 788 PetscErrorCode ierr; 789 790 PetscFunctionBegin; 791 ierr = PetscTryMethod(ts,"TSSundialsSetGramSchmidtType_C",(TS,TSSundialsGramSchmidtType),(ts,type));CHKERRQ(ierr); 792 PetscFunctionReturn(0); 793 } 794 795 #undef __FUNCT__ 796 #define __FUNCT__ "TSSundialsSetTolerance" 797 /*@ 798 TSSundialsSetTolerance - Sets the absolute and relative tolerance used by 799 Sundials for error control. 800 801 Logically Collective on TS 802 803 Input parameters: 804 + ts - the time-step context 805 . aabs - the absolute tolerance 806 - rel - the relative tolerance 807 808 See the Cvode/Sundials users manual for exact details on these parameters. Essentially 809 these regulate the size of the error for a SINGLE timestep. 810 811 Level: intermediate 812 813 .keywords: Sundials, tolerance 814 815 .seealso: TSSundialsGetIterations(), TSSundialsSetType(), TSSundialsSetGMRESRestart(), 816 TSSundialsSetLinearTolerance(), TSSundialsSetGramSchmidtType(), 817 TSSundialsGetIterations(), TSSundialsSetType(), TSSundialsSetGMRESRestart(), 818 TSSundialsSetLinearTolerance(), TSSundialsSetTolerance(), TSSundialsGetPC(), 819 TSSundialsSetExactFinalTime() 820 821 @*/ 822 PetscErrorCode TSSundialsSetTolerance(TS ts,double aabs,double rel) 823 { 824 PetscErrorCode ierr; 825 826 PetscFunctionBegin; 827 ierr = PetscTryMethod(ts,"TSSundialsSetTolerance_C",(TS,double,double),(ts,aabs,rel));CHKERRQ(ierr); 828 PetscFunctionReturn(0); 829 } 830 831 #undef __FUNCT__ 832 #define __FUNCT__ "TSSundialsGetPC" 833 /*@ 834 TSSundialsGetPC - Extract the PC context from a time-step context for Sundials. 835 836 Input Parameter: 837 . ts - the time-step context 838 839 Output Parameter: 840 . pc - the preconditioner context 841 842 Level: advanced 843 844 .seealso: TSSundialsGetIterations(), TSSundialsSetType(), TSSundialsSetGMRESRestart(), 845 TSSundialsSetLinearTolerance(), TSSundialsSetGramSchmidtType(), TSSundialsSetTolerance(), 846 TSSundialsGetIterations(), TSSundialsSetType(), TSSundialsSetGMRESRestart(), 847 TSSundialsSetLinearTolerance(), TSSundialsSetTolerance() 848 @*/ 849 PetscErrorCode TSSundialsGetPC(TS ts,PC *pc) 850 { 851 PetscErrorCode ierr; 852 853 PetscFunctionBegin; 854 ierr = PetscUseMethod(ts,"TSSundialsGetPC_C",(TS,PC *),(ts,pc));CHKERRQ(ierr); 855 PetscFunctionReturn(0); 856 } 857 858 #undef __FUNCT__ 859 #define __FUNCT__ "TSSundialsSetExactFinalTime" 860 /*@ 861 TSSundialsSetExactFinalTime - Determines if Sundials interpolates solution to the 862 exact final time requested by the user or just returns it at the final time 863 it computed. (Defaults to true). 864 865 Input Parameter: 866 + ts - the time-step context 867 - ft - PETSC_TRUE if interpolates, else PETSC_FALSE 868 869 Level: beginner 870 871 .seealso:TSSundialsGetIterations(), TSSundialsSetType(), TSSundialsSetGMRESRestart(), 872 TSSundialsSetLinearTolerance(), TSSundialsSetGramSchmidtType(), TSSundialsSetTolerance(), 873 TSSundialsGetIterations(), TSSundialsSetType(), TSSundialsSetGMRESRestart(), 874 TSSundialsSetLinearTolerance(), TSSundialsSetTolerance(), TSSundialsGetPC() 875 @*/ 876 PetscErrorCode TSSundialsSetExactFinalTime(TS ts,PetscBool ft) 877 { 878 PetscErrorCode ierr; 879 880 PetscFunctionBegin; 881 ierr = PetscTryMethod(ts,"TSSundialsSetExactFinalTime_C",(TS,PetscBool),(ts,ft));CHKERRQ(ierr); 882 PetscFunctionReturn(0); 883 } 884 885 #undef __FUNCT__ 886 #define __FUNCT__ "TSSundialsSetMinTimeStep" 887 /*@ 888 TSSundialsSetMinTimeStep - Smallest time step to be chosen by the adaptive controller. 889 890 Input Parameter: 891 + ts - the time-step context 892 - mindt - lowest time step if positive, negative to deactivate 893 894 Note: 895 Sundials will error if it is not possible to keep the estimated truncation error below 896 the tolerance set with TSSundialsSetTolerance() without going below this step size. 897 898 Level: beginner 899 900 .seealso: TSSundialsSetType(), TSSundialsSetTolerance(), 901 @*/ 902 PetscErrorCode TSSundialsSetMinTimeStep(TS ts,PetscReal mindt) 903 { 904 PetscErrorCode ierr; 905 906 PetscFunctionBegin; 907 ierr = PetscTryMethod(ts,"TSSundialsSetMinTimeStep_C",(TS,PetscReal),(ts,mindt));CHKERRQ(ierr); 908 PetscFunctionReturn(0); 909 } 910 911 #undef __FUNCT__ 912 #define __FUNCT__ "TSSundialsSetMaxTimeStep" 913 /*@ 914 TSSundialsSetMaxTimeStep - Largest time step to be chosen by the adaptive controller. 915 916 Input Parameter: 917 + ts - the time-step context 918 - maxdt - lowest time step if positive, negative to deactivate 919 920 Level: beginner 921 922 .seealso: TSSundialsSetType(), TSSundialsSetTolerance(), 923 @*/ 924 PetscErrorCode TSSundialsSetMaxTimeStep(TS ts,PetscReal maxdt) 925 { 926 PetscErrorCode ierr; 927 928 PetscFunctionBegin; 929 ierr = PetscTryMethod(ts,"TSSundialsSetMaxTimeStep_C",(TS,PetscReal),(ts,maxdt));CHKERRQ(ierr); 930 PetscFunctionReturn(0); 931 } 932 933 #undef __FUNCT__ 934 #define __FUNCT__ "TSSundialsMonitorInternalSteps" 935 /*@ 936 TSSundialsMonitorInternalSteps - Monitor Sundials internal steps (Defaults to false). 937 938 Input Parameter: 939 + ts - the time-step context 940 - ft - PETSC_TRUE if monitor, else PETSC_FALSE 941 942 Level: beginner 943 944 .seealso:TSSundialsGetIterations(), TSSundialsSetType(), TSSundialsSetGMRESRestart(), 945 TSSundialsSetLinearTolerance(), TSSundialsSetGramSchmidtType(), TSSundialsSetTolerance(), 946 TSSundialsGetIterations(), TSSundialsSetType(), TSSundialsSetGMRESRestart(), 947 TSSundialsSetLinearTolerance(), TSSundialsSetTolerance(), TSSundialsGetPC() 948 @*/ 949 PetscErrorCode TSSundialsMonitorInternalSteps(TS ts,PetscBool ft) 950 { 951 PetscErrorCode ierr; 952 953 PetscFunctionBegin; 954 ierr = PetscTryMethod(ts,"TSSundialsMonitorInternalSteps_C",(TS,PetscBool),(ts,ft));CHKERRQ(ierr); 955 PetscFunctionReturn(0); 956 } 957 /* -------------------------------------------------------------------------------------------*/ 958 /*MC 959 TSSUNDIALS - ODE solver using the LLNL CVODE/SUNDIALS package (now called SUNDIALS) 960 961 Options Database: 962 + -ts_sundials_type <bdf,adams> 963 . -ts_sundials_gramschmidt_type <modified, classical> - type of orthogonalization inside GMRES 964 . -ts_sundials_atol <tol> - Absolute tolerance for convergence 965 . -ts_sundials_rtol <tol> - Relative tolerance for convergence 966 . -ts_sundials_linear_tolerance <tol> 967 . -ts_sundials_gmres_restart <restart> - Number of GMRES orthogonalization directions 968 . -ts_sundials_exact_final_time - Interpolate output to stop exactly at the final time 969 - -ts_sundials_monitor_steps - Monitor SUNDIALS internel steps 970 971 972 Notes: This uses its own nonlinear solver and Krylov method so PETSc SNES and KSP options do not apply 973 only PETSc PC options 974 975 Level: beginner 976 977 .seealso: TSCreate(), TS, TSSetType(), TSSundialsSetType(), TSSundialsSetGMRESRestart(), TSSundialsSetLinearTolerance(), 978 TSSundialsSetGramSchmidtType(), TSSundialsSetTolerance(), TSSundialsGetPC(), TSSundialsGetIterations(), TSSundialsSetExactFinalTime() 979 980 M*/ 981 EXTERN_C_BEGIN 982 #undef __FUNCT__ 983 #define __FUNCT__ "TSCreate_Sundials" 984 PetscErrorCode TSCreate_Sundials(TS ts) 985 { 986 TS_Sundials *cvode; 987 PetscErrorCode ierr; 988 989 PetscFunctionBegin; 990 ts->ops->reset = TSReset_Sundials; 991 ts->ops->destroy = TSDestroy_Sundials; 992 ts->ops->view = TSView_Sundials; 993 ts->ops->setup = TSSetUp_Sundials; 994 ts->ops->solve = TSSolve_Sundials; 995 ts->ops->setfromoptions = TSSetFromOptions_Sundials; 996 997 ierr = PetscNewLog(ts,TS_Sundials,&cvode);CHKERRQ(ierr); 998 ts->data = (void*)cvode; 999 cvode->cvode_type = SUNDIALS_BDF; 1000 cvode->gtype = SUNDIALS_CLASSICAL_GS; 1001 cvode->restart = 5; 1002 cvode->linear_tol = .05; 1003 1004 cvode->exact_final_time = PETSC_TRUE; 1005 cvode->monitorstep = PETSC_FALSE; 1006 1007 ierr = MPI_Comm_dup(((PetscObject)ts)->comm,&(cvode->comm_sundials));CHKERRQ(ierr); 1008 1009 cvode->mindt = -1.; 1010 cvode->maxdt = -1.; 1011 1012 /* set tolerance for Sundials */ 1013 cvode->reltol = 1e-6; 1014 cvode->abstol = 1e-6; 1015 1016 ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSSundialsSetType_C","TSSundialsSetType_Sundials", 1017 TSSundialsSetType_Sundials);CHKERRQ(ierr); 1018 ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSSundialsSetGMRESRestart_C", 1019 "TSSundialsSetGMRESRestart_Sundials", 1020 TSSundialsSetGMRESRestart_Sundials);CHKERRQ(ierr); 1021 ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSSundialsSetLinearTolerance_C", 1022 "TSSundialsSetLinearTolerance_Sundials", 1023 TSSundialsSetLinearTolerance_Sundials);CHKERRQ(ierr); 1024 ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSSundialsSetGramSchmidtType_C", 1025 "TSSundialsSetGramSchmidtType_Sundials", 1026 TSSundialsSetGramSchmidtType_Sundials);CHKERRQ(ierr); 1027 ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSSundialsSetTolerance_C", 1028 "TSSundialsSetTolerance_Sundials", 1029 TSSundialsSetTolerance_Sundials);CHKERRQ(ierr); 1030 ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSSundialsSetMinTimeStep_C", 1031 "TSSundialsSetMinTimeStep_Sundials", 1032 TSSundialsSetMinTimeStep_Sundials);CHKERRQ(ierr); 1033 ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSSundialsSetMaxTimeStep_C", 1034 "TSSundialsSetMaxTimeStep_Sundials", 1035 TSSundialsSetMaxTimeStep_Sundials);CHKERRQ(ierr); 1036 ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSSundialsGetPC_C", 1037 "TSSundialsGetPC_Sundials", 1038 TSSundialsGetPC_Sundials);CHKERRQ(ierr); 1039 ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSSundialsGetIterations_C", 1040 "TSSundialsGetIterations_Sundials", 1041 TSSundialsGetIterations_Sundials);CHKERRQ(ierr); 1042 ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSSundialsSetExactFinalTime_C", 1043 "TSSundialsSetExactFinalTime_Sundials", 1044 TSSundialsSetExactFinalTime_Sundials);CHKERRQ(ierr); 1045 ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSSundialsMonitorInternalSteps_C", 1046 "TSSundialsMonitorInternalSteps_Sundials", 1047 TSSundialsMonitorInternalSteps_Sundials);CHKERRQ(ierr); 1048 1049 PetscFunctionReturn(0); 1050 } 1051 EXTERN_C_END 1052