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