Actual source code: sundials.c
1: #define PETSCTS_DLL
3: /*
4: Provides a PETSc interface to SUNDIALS. Alan Hindmarsh's parallel ODE
5: solver.
6: The interface to PVODE (old version of CVODE) was originally contributed
7: by Liyang Xu. It has been redone by Hong Zhang and Dinesh Kaushik.
8: */
10: #include "src/ts/impls/implicit/sundials/sundials.h" /*I "petscts.h" I*/
12: /*
13: TSPrecond_Sundials - function that we provide to SUNDIALS to
14: evaluate the preconditioner.
15: */
18: PetscErrorCode TSPrecond_Sundials(realtype tn,N_Vector y,N_Vector fy,
19: booleantype jok,booleantype *jcurPtr,
20: realtype _gamma,void *P_data,
21: N_Vector vtemp1,N_Vector vtemp2,N_Vector vtemp3)
22: {
23: TS ts = (TS) P_data;
24: TS_Sundials *cvode = (TS_Sundials*)ts->data;
25: PC pc = cvode->pc;
27: Mat Jac = ts->B;
28: Vec yy = cvode->w1;
29: PetscScalar one = 1.0,gm;
30: MatStructure str = DIFFERENT_NONZERO_PATTERN;
31: PetscScalar *y_data;
32:
34: /* This allows us to construct preconditioners in-place if we like */
35: MatSetUnfactored(Jac);
36:
37: /* jok - TRUE means reuse current Jacobian else recompute Jacobian */
38: if (jok) {
39: MatCopy(cvode->pmat,Jac,str);
40: *jcurPtr = FALSE;
41: } else {
42: /* make PETSc vector yy point to SUNDIALS vector y */
43: y_data = (PetscScalar *) N_VGetArrayPointer(y);
44: VecPlaceArray(yy,y_data);
45: /* compute the Jacobian */
46: TSComputeRHSJacobian(ts,ts->ptime,yy,&Jac,&Jac,&str);
47: VecResetArray(yy);
48: /* copy the Jacobian matrix */
49: if (!cvode->pmat) {
50: MatDuplicate(Jac,MAT_COPY_VALUES,&cvode->pmat);
51: PetscLogObjectParent(ts,cvode->pmat);
52: }
53: else {
54: MatCopy(Jac,cvode->pmat,str);
55: }
56: *jcurPtr = TRUE;
57: }
58:
59: /* construct I-gamma*Jac */
60: gm = -_gamma;
61: MatScale(Jac,gm);
62: MatShift(Jac,one);
63:
64: PCSetOperators(pc,Jac,Jac,str);
65: return(0);
66: }
68: /*
69: TSPSolve_Sundials - routine that we provide to Sundials that applies the preconditioner.
70: */
73: PetscErrorCode TSPSolve_Sundials(realtype tn,N_Vector y,N_Vector fy,
74: N_Vector r,N_Vector z,
75: realtype _gamma,realtype delta,
76: int lr,void *P_data,N_Vector vtemp)
77: {
78: TS ts = (TS) P_data;
79: TS_Sundials *cvode = (TS_Sundials*)ts->data;
80: PC pc = cvode->pc;
81: Vec rr = cvode->w1,zz = cvode->w2;
82: PetscErrorCode ierr;
83: PetscScalar *r_data,*z_data;
86: /* Make the PETSc work vectors rr and zz point to the arrays in the SUNDIALS vectors r and z respectively*/
87: r_data = (PetscScalar *) N_VGetArrayPointer(r);
88: z_data = (PetscScalar *) N_VGetArrayPointer(z);
89: VecPlaceArray(rr,r_data);
90: VecPlaceArray(zz,z_data);
91: /* Solve the Px=r and put the result in zz */
92: PCApply(pc,rr,zz);
93: VecResetArray(rr);
94: VecResetArray(zz);
95: cvode->linear_solves++;
96: return(0);
97: }
99: /*
100: TSFunction_Sundials - routine that we provide to Sundials that applies the right hand side.
101: */
104: void TSFunction_Sundials(realtype t,N_Vector y,N_Vector ydot,void *ctx)
105: {
106: TS ts = (TS) ctx;
107: MPI_Comm comm = ts->comm;
108: TS_Sundials *cvode = (TS_Sundials*)ts->data;
109: Vec yy = cvode->w1,yyd = cvode->w2;
110: PetscScalar *y_data,*ydot_data;
111: PetscErrorCode ierr;
114: /* Make the PETSc work vectors yy and yyd point to the arrays in the SUNDIALS vectors y and ydot respectively*/
115: y_data = (PetscScalar *) N_VGetArrayPointer(y);
116: ydot_data = (PetscScalar *) N_VGetArrayPointer(ydot);
117: VecPlaceArray(yy,y_data);CHKERRABORT(comm,ierr)
118: VecPlaceArray(yyd,ydot_data); CHKERRABORT(comm,ierr)
119: /* now compute the right hand side function */
120: TSComputeRHSFunction(ts,t,yy,yyd); CHKERRABORT(comm,ierr);
121: VecResetArray(yy); CHKERRABORT(comm,ierr);
122: VecResetArray(yyd); CHKERRABORT(comm,ierr);
123: PetscFunctionReturnVoid();
124: }
126: /*
127: TSStep_Sundials_Nonlinear - Calls Sundials to integrate the ODE.
128: */
131: /*
132: TSStep_Sundials_Nonlinear -
133:
134: steps - number of time steps
135: time - time that integrater is terminated.
136: */
137: PetscErrorCode TSStep_Sundials_Nonlinear(TS ts,int *steps,double *time)
138: {
139: TS_Sundials *cvode = (TS_Sundials*)ts->data;
140: Vec sol = ts->vec_sol;
142: int i,max_steps = ts->max_steps,flag;
143: long int its;
144: realtype t,tout;
145: PetscScalar *y_data;
146: void *mem;
149: /*
150: Call CVodeCreate to create the solver memory:
151: CV_ADAMS specifies the Adams Method
152: CV_FUNCTIONAL specifies functional iteration
153: A pointer to the integrator memory is returned and stored in cvode_mem.
154: */
155: mem = CVodeCreate(cvode->cvode_type, CV_NEWTON);
156: if (!mem) SETERRQ(1,"CVodeCreate() fails");
157: flag = CVodeSetFdata(mem,ts);
158: if (flag) SETERRQ(1,"CVodeSetFdata() fails");
160: /*
161: Call CVodeMalloc to initialize the integrator memory:
162: mem is the pointer to the integrator memory returned by CVodeCreate
163: f is the user's right hand side function in y'=f(t,y)
164: T0 is the initial time
165: u is the initial dependent variable vector
166: CV_SS specifies scalar relative and absolute tolerances
167: reltol is the relative tolerance
168: &abstol is a pointer to the scalar absolute tolerance
169: */
170: flag = CVodeMalloc(mem,TSFunction_Sundials,ts->ptime,cvode->y,CV_SS,cvode->reltol,&cvode->abstol);
171: if (flag) SETERRQ(1,"CVodeMalloc() fails");
173: /* initialize the number of steps */
174: *steps = -ts->steps;
175: TSMonitor(ts,ts->steps,ts->ptime,sol);
177: /* call CVSpgmr to use GMRES as the linear solver. */
178: /* setup the ode integrator with the given preconditioner */
179: /* flag = CVSpgmr(mem,PREC_LEFT,cvode->restart); */
180: flag = CVSpgmr(mem,PREC_LEFT,0);
181: if (flag) SETERRQ(1,"CVSpgmr() fails");
182: flag = CVSpgmrSetGSType(mem,MODIFIED_GS);
183: if (flag) SETERRQ(1,"CVSpgmrSetGSType() fails");
185: /* Set preconditioner setup and solve routines Precond and PSolve,
186: and the pointer to the user-defined block data */
187: flag = CVSpgmrSetPreconditioner(mem,TSPrecond_Sundials,TSPSolve_Sundials,ts);
188: if (flag) SETERRQ(1,"CVSpgmrSetPreconditioner() fails");
190: tout = ts->max_time;
191: VecGetArray(ts->vec_sol,&y_data);
192: N_VSetArrayPointer((realtype *)y_data,cvode->y);
193: VecRestoreArray(ts->vec_sol,PETSC_NULL);
194: for (i = 0; i < max_steps; i++) {
195: if (ts->ptime >= ts->max_time) break;
196: CVode(mem,tout,cvode->y,&t,CV_ONE_STEP);
197: CVodeGetNumNonlinSolvIters(mem,&its);
198: cvode->nonlinear_solves += its;
200: if (t > ts->max_time && cvode->exact_final_time) {
201: /* interpolate to final requested time */
202: CVodeGetDky(mem,tout,0,cvode->y);
203: t = tout;
204: }
205: ts->time_step = t - ts->ptime;
206: ts->ptime = t;
208: /* copy the solution from cvode->y to cvode->update and sol */
209: VecPlaceArray(cvode->w1,y_data);
210: VecCopy(cvode->w1,cvode->update);
211: VecResetArray(cvode->w1);
212: VecCopy(cvode->update,sol);
213: CVodeGetNumNonlinSolvIters(mem,&its);
214: ts->nonlinear_its = its;
215: CVSpgmrGetNumLinIters(mem, &its);
216: ts->linear_its = its;
217: ts->steps++;
218: TSMonitor(ts,ts->steps,t,sol);
219: }
220: CVodeFree(mem);
221: *steps += ts->steps;
222: *time = t;
223: return(0);
224: }
228: PetscErrorCode TSDestroy_Sundials(TS ts)
229: {
230: TS_Sundials *cvode = (TS_Sundials*)ts->data;
234: if (cvode->pmat) {MatDestroy(cvode->pmat);}
235: if (cvode->pc) {PCDestroy(cvode->pc);}
236: if (cvode->update) {VecDestroy(cvode->update);}
237: if (cvode->func) {VecDestroy(cvode->func);}
238: if (cvode->rhs) {VecDestroy(cvode->rhs);}
239: if (cvode->w1) {VecDestroy(cvode->w1);}
240: if (cvode->w2) {VecDestroy(cvode->w2);}
241: MPI_Comm_free(&(cvode->comm_sundials));
242: PetscFree(cvode);
243: return(0);
244: }
248: PetscErrorCode TSSetUp_Sundials_Nonlinear(TS ts)
249: {
250: TS_Sundials *cvode = (TS_Sundials*)ts->data;
252: int glosize,locsize,i;
253: PetscScalar *y_data,*parray;
256: PCSetFromOptions(cvode->pc);
257: /* get the vector size */
258: VecGetSize(ts->vec_sol,&glosize);
259: VecGetLocalSize(ts->vec_sol,&locsize);
261: /* allocate the memory for N_Vec y */
262: cvode->y = N_VNew_Parallel(cvode->comm_sundials,locsize,glosize);
263: if (!cvode->y) SETERRQ(1,"cvode->y is not allocated");
265: /* initialize N_Vec y */
266: VecGetArray(ts->vec_sol,&parray);
267: y_data = (PetscScalar *) N_VGetArrayPointer(cvode->y);
268: for (i = 0; i < locsize; i++) y_data[i] = parray[i];
269: /*PetscMemcpy(y_data,parray,locsize*sizeof(PETSC_SCALAR)); */
270: VecRestoreArray(ts->vec_sol,PETSC_NULL);
271: VecDuplicate(ts->vec_sol,&cvode->update);
272: VecDuplicate(ts->vec_sol,&cvode->func);
273: PetscLogObjectParent(ts,cvode->update);
274: PetscLogObjectParent(ts,cvode->func);
276: /*
277: Create work vectors for the TSPSolve_Sundials() routine. Note these are
278: allocated with zero space arrays because the actual array space is provided
279: by Sundials and set using VecPlaceArray().
280: */
281: VecCreateMPIWithArray(ts->comm,locsize,PETSC_DECIDE,0,&cvode->w1);
282: VecCreateMPIWithArray(ts->comm,locsize,PETSC_DECIDE,0,&cvode->w2);
283: PetscLogObjectParent(ts,cvode->w1);
284: PetscLogObjectParent(ts,cvode->w2);
285: return(0);
286: }
290: PetscErrorCode TSSetFromOptions_Sundials_Nonlinear(TS ts)
291: {
292: TS_Sundials *cvode = (TS_Sundials*)ts->data;
294: int indx;
295: const char *btype[] = {"bdf","adams"},*otype[] = {"modified","unmodified"};
296: PetscTruth flag;
299: PetscOptionsHead("SUNDIALS ODE solver options");
300: PetscOptionsEList("-ts_sundials_type","Scheme","TSSundialsSetType",btype,2,"bdf",&indx,&flag);
301: if (flag) {
302: TSSundialsSetType(ts,(TSSundialsType)indx);
303: }
304: PetscOptionsEList("-ts_sundials_gramschmidt_type","Type of orthogonalization","TSSundialsSetGramSchmidtType",otype,2,"unmodified",&indx,&flag);
305: if (flag) {
306: TSSundialsSetGramSchmidtType(ts,(TSSundialsGramSchmidtType)indx);
307: }
308: PetscOptionsReal("-ts_sundials_atol","Absolute tolerance for convergence","TSSundialsSetTolerance",cvode->abstol,&cvode->abstol,PETSC_NULL);
309: PetscOptionsReal("-ts_sundials_rtol","Relative tolerance for convergence","TSSundialsSetTolerance",cvode->reltol,&cvode->reltol,PETSC_NULL);
310: PetscOptionsReal("-ts_sundials_linear_tolerance","Convergence tolerance for linear solve","TSSundialsSetLinearTolerance",cvode->linear_tol,&cvode->linear_tol,&flag);
311: PetscOptionsInt("-ts_sundials_gmres_restart","Number of GMRES orthogonalization directions","TSSundialsSetGMRESRestart",cvode->restart,&cvode->restart,&flag);
312: PetscOptionsName("-ts_sundials_exact_final_time","Allow SUNDIALS to stop near the final time, not exactly on it","TSSundialsSetExactFinalTime",&cvode->exact_final_time);
313: PetscOptionsTail();
314: return(0);
315: }
319: PetscErrorCode TSPrintHelp_Sundials(TS ts,char *p)
320: {
324: (*PetscHelpPrintf)(ts->comm," Options for TSSUNDIALS integrater:\n");
325: (*PetscHelpPrintf)(ts->comm," -ts_sundials_type <bdf,adams>: integration approach\n",p);
326: (*PetscHelpPrintf)(ts->comm," -ts_sundials_atol aabs: absolute tolerance of ODE solution\n",p);
327: (*PetscHelpPrintf)(ts->comm," -ts_sundials_rtol rel: relative tolerance of ODE solution\n",p);
328: (*PetscHelpPrintf)(ts->comm," -ts_sundials_gramschmidt_type <unmodified,modified>\n");
329: (*PetscHelpPrintf)(ts->comm," -ts_sundials_gmres_restart <restart_size> (also max. GMRES its)\n");
330: (*PetscHelpPrintf)(ts->comm," -ts_sundials_linear_tolerance <tol>\n");
331: (*PetscHelpPrintf)(ts->comm," -ts_sundials_not_exact_final_time\n");
332: return(0);
333: }
337: PetscErrorCode TSView_Sundials(TS ts,PetscViewer viewer)
338: {
339: TS_Sundials *cvode = (TS_Sundials*)ts->data;
341: char *type;
342: char atype[] = "Adams";
343: char btype[] = "BDF: backward differentiation formula";
344: PetscTruth iascii,isstring;
347: if (cvode->cvode_type == SUNDIALS_ADAMS) {type = atype;}
348: else {type = btype;}
350: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
351: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_STRING,&isstring);
352: if (iascii) {
353: PetscViewerASCIIPrintf(viewer,"Sundials integrater does not use SNES!\n");
354: PetscViewerASCIIPrintf(viewer,"Sundials integrater type %s\n",type);
355: PetscViewerASCIIPrintf(viewer,"Sundials abs tol %g rel tol %g\n",cvode->abstol,cvode->reltol);
356: PetscViewerASCIIPrintf(viewer,"Sundials linear solver tolerance factor %g\n",cvode->linear_tol);
357: PetscViewerASCIIPrintf(viewer,"Sundials GMRES max iterations (same as restart in SUNDIALS) %D\n",cvode->restart);
358: if (cvode->gtype == SUNDIALS_MODIFIED_GS) {
359: PetscViewerASCIIPrintf(viewer,"Sundials using modified Gram-Schmidt for orthogonalization in GMRES\n");
360: } else {
361: PetscViewerASCIIPrintf(viewer,"Sundials using unmodified (classical) Gram-Schmidt for orthogonalization in GMRES\n");
362: }
363: } else if (isstring) {
364: PetscViewerStringSPrintf(viewer,"Sundials type %s",type);
365: } else {
366: SETERRQ1(PETSC_ERR_SUP,"Viewer type %s not supported by TS Sundials",((PetscObject)viewer)->type_name);
367: }
368: PetscViewerASCIIPushTab(viewer);
369: PCView(cvode->pc,viewer);
370: PetscViewerASCIIPopTab(viewer);
371: return(0);
372: }
375: /* --------------------------------------------------------------------------*/
379: PetscErrorCode PETSCTS_DLLEXPORT TSSundialsSetType_Sundials(TS ts,TSSundialsType type)
380: {
381: TS_Sundials *cvode = (TS_Sundials*)ts->data;
382:
384: cvode->cvode_type = type;
385: return(0);
386: }
392: PetscErrorCode PETSCTS_DLLEXPORT TSSundialsSetGMRESRestart_Sundials(TS ts,int restart)
393: {
394: TS_Sundials *cvode = (TS_Sundials*)ts->data;
395:
397: cvode->restart = restart;
398: return(0);
399: }
405: PetscErrorCode PETSCTS_DLLEXPORT TSSundialsSetLinearTolerance_Sundials(TS ts,double tol)
406: {
407: TS_Sundials *cvode = (TS_Sundials*)ts->data;
408:
410: cvode->linear_tol = tol;
411: return(0);
412: }
418: PetscErrorCode PETSCTS_DLLEXPORT TSSundialsSetGramSchmidtType_Sundials(TS ts,TSSundialsGramSchmidtType type)
419: {
420: TS_Sundials *cvode = (TS_Sundials*)ts->data;
421:
423: cvode->gtype = type;
424: return(0);
425: }
431: PetscErrorCode PETSCTS_DLLEXPORT TSSundialsSetTolerance_Sundials(TS ts,double aabs,double rel)
432: {
433: TS_Sundials *cvode = (TS_Sundials*)ts->data;
434:
436: if (aabs != PETSC_DECIDE) cvode->abstol = aabs;
437: if (rel != PETSC_DECIDE) cvode->reltol = rel;
438: return(0);
439: }
445: PetscErrorCode PETSCTS_DLLEXPORT TSSundialsGetPC_Sundials(TS ts,PC *pc)
446: {
447: TS_Sundials *cvode = (TS_Sundials*)ts->data;
450: *pc = cvode->pc;
451: return(0);
452: }
458: PetscErrorCode PETSCTS_DLLEXPORT TSSundialsGetIterations_Sundials(TS ts,int *nonlin,int *lin)
459: {
460: TS_Sundials *cvode = (TS_Sundials*)ts->data;
461:
463: if (nonlin) *nonlin = cvode->nonlinear_solves;
464: if (lin) *lin = cvode->linear_solves;
465: return(0);
466: }
468:
472: PetscErrorCode PETSCTS_DLLEXPORT TSSundialsSetExactFinalTime_Sundials(TS ts,PetscTruth s)
473: {
474: TS_Sundials *cvode = (TS_Sundials*)ts->data;
475:
477: cvode->exact_final_time = s;
478: return(0);
479: }
481: /* -------------------------------------------------------------------------------------------*/
485: /*@C
486: TSSundialsGetIterations - Gets the number of nonlinear and linear iterations used so far by Sundials.
488: Not Collective
490: Input parameters:
491: . ts - the time-step context
493: Output Parameters:
494: + nonlin - number of nonlinear iterations
495: - lin - number of linear iterations
497: Level: advanced
499: Notes:
500: These return the number since the creation of the TS object
502: .keywords: non-linear iterations, linear iterations
504: .seealso: TSSundialsSetType(), TSSundialsSetGMRESRestart(),
505: TSSundialsSetLinearTolerance(), TSSundialsSetGramSchmidtType(), TSSundialsSetTolerance(),
506: TSSundialsGetIterations(), TSSundialsSetType(), TSSundialsSetGMRESRestart(),
507: TSSundialsSetLinearTolerance(), TSSundialsSetTolerance(), TSSundialsGetPC(),
508: TSSundialsSetExactFinalTime()
510: @*/
511: PetscErrorCode PETSCTS_DLLEXPORT TSSundialsGetIterations(TS ts,int *nonlin,int *lin)
512: {
513: PetscErrorCode ierr,(*f)(TS,int*,int*);
514:
516: PetscObjectQueryFunction((PetscObject)ts,"TSSundialsGetIterations_C",(void (**)(void))&f);
517: if (f) {
518: (*f)(ts,nonlin,lin);
519: }
520: return(0);
521: }
525: /*@
526: TSSundialsSetType - Sets the method that Sundials will use for integration.
528: Collective on TS
530: Input parameters:
531: + ts - the time-step context
532: - type - one of SUNDIALS_ADAMS or SUNDIALS_BDF
534: Level: intermediate
536: .keywords: Adams, backward differentiation formula
538: .seealso: TSSundialsGetIterations(), TSSundialsSetGMRESRestart(),
539: TSSundialsSetLinearTolerance(), TSSundialsSetGramSchmidtType(), TSSundialsSetTolerance(),
540: TSSundialsGetIterations(), TSSundialsSetType(), TSSundialsSetGMRESRestart(),
541: TSSundialsSetLinearTolerance(), TSSundialsSetTolerance(), TSSundialsGetPC(),
542: TSSundialsSetExactFinalTime()
543: @*/
544: PetscErrorCode PETSCTS_DLLEXPORT TSSundialsSetType(TS ts,TSSundialsType type)
545: {
546: PetscErrorCode ierr,(*f)(TS,TSSundialsType);
547:
549: PetscObjectQueryFunction((PetscObject)ts,"TSSundialsSetType_C",(void (**)(void))&f);
550: if (f) {
551: (*f)(ts,type);
552: }
553: return(0);
554: }
558: /*@
559: TSSundialsSetGMRESRestart - Sets the dimension of the Krylov space used by
560: GMRES in the linear solver in SUNDIALS. SUNDIALS DOES NOT use restarted GMRES so
561: this is ALSO the maximum number of GMRES steps that will be used.
563: Collective on TS
565: Input parameters:
566: + ts - the time-step context
567: - restart - number of direction vectors (the restart size).
569: Level: advanced
571: .keywords: GMRES, restart
573: .seealso: TSSundialsGetIterations(), TSSundialsSetType(),
574: TSSundialsSetLinearTolerance(), TSSundialsSetGramSchmidtType(), TSSundialsSetTolerance(),
575: TSSundialsGetIterations(), TSSundialsSetType(), TSSundialsSetGMRESRestart(),
576: TSSundialsSetLinearTolerance(), TSSundialsSetTolerance(), TSSundialsGetPC(),
577: TSSundialsSetExactFinalTime()
579: @*/
580: PetscErrorCode PETSCTS_DLLEXPORT TSSundialsSetGMRESRestart(TS ts,int restart)
581: {
582: PetscErrorCode ierr,(*f)(TS,int);
585: PetscObjectQueryFunction((PetscObject)ts,"TSSundialsSetGMRESRestart_C",(void (**)(void))&f);
586: if (f) {
587: (*f)(ts,restart);
588: }
589: return(0);
590: }
594: /*@
595: TSSundialsSetLinearTolerance - Sets the tolerance used to solve the linear
596: system by SUNDIALS.
598: Collective on TS
600: Input parameters:
601: + ts - the time-step context
602: - tol - the factor by which the tolerance on the nonlinear solver is
603: multiplied to get the tolerance on the linear solver, .05 by default.
605: Level: advanced
607: .keywords: GMRES, linear convergence tolerance, SUNDIALS
609: .seealso: TSSundialsGetIterations(), TSSundialsSetType(), TSSundialsSetGMRESRestart(),
610: TSSundialsSetGramSchmidtType(), TSSundialsSetTolerance(),
611: TSSundialsGetIterations(), TSSundialsSetType(), TSSundialsSetGMRESRestart(),
612: TSSundialsSetLinearTolerance(), TSSundialsSetTolerance(), TSSundialsGetPC(),
613: TSSundialsSetExactFinalTime()
615: @*/
616: PetscErrorCode PETSCTS_DLLEXPORT TSSundialsSetLinearTolerance(TS ts,double tol)
617: {
618: PetscErrorCode ierr,(*f)(TS,double);
619:
621: PetscObjectQueryFunction((PetscObject)ts,"TSSundialsSetLinearTolerance_C",(void (**)(void))&f);
622: if (f) {
623: (*f)(ts,tol);
624: }
625: return(0);
626: }
630: /*@
631: TSSundialsSetGramSchmidtType - Sets type of orthogonalization used
632: in GMRES method by SUNDIALS linear solver.
634: Collective on TS
636: Input parameters:
637: + ts - the time-step context
638: - type - either SUNDIALS_MODIFIED_GS or SUNDIALS_CLASSICAL_GS
640: Level: advanced
642: .keywords: Sundials, orthogonalization
644: .seealso: TSSundialsGetIterations(), TSSundialsSetType(), TSSundialsSetGMRESRestart(),
645: TSSundialsSetLinearTolerance(), TSSundialsSetTolerance(),
646: TSSundialsGetIterations(), TSSundialsSetType(), TSSundialsSetGMRESRestart(),
647: TSSundialsSetLinearTolerance(), TSSundialsSetTolerance(), TSSundialsGetPC(),
648: TSSundialsSetExactFinalTime()
650: @*/
651: PetscErrorCode PETSCTS_DLLEXPORT TSSundialsSetGramSchmidtType(TS ts,TSSundialsGramSchmidtType type)
652: {
653: PetscErrorCode ierr,(*f)(TS,TSSundialsGramSchmidtType);
654:
656: PetscObjectQueryFunction((PetscObject)ts,"TSSundialsSetGramSchmidtType_C",(void (**)(void))&f);
657: if (f) {
658: (*f)(ts,type);
659: }
660: return(0);
661: }
665: /*@
666: TSSundialsSetTolerance - Sets the absolute and relative tolerance used by
667: Sundials for error control.
669: Collective on TS
671: Input parameters:
672: + ts - the time-step context
673: . aabs - the absolute tolerance
674: - rel - the relative tolerance
676: See the Cvode/Sundials users manual for exact details on these parameters. Essentially
677: these regulate the size of the error for a SINGLE timestep.
679: Level: intermediate
681: .keywords: Sundials, tolerance
683: .seealso: TSSundialsGetIterations(), TSSundialsSetType(), TSSundialsSetGMRESRestart(),
684: TSSundialsSetLinearTolerance(), TSSundialsSetGramSchmidtType(),
685: TSSundialsGetIterations(), TSSundialsSetType(), TSSundialsSetGMRESRestart(),
686: TSSundialsSetLinearTolerance(), TSSundialsSetTolerance(), TSSundialsGetPC(),
687: TSSundialsSetExactFinalTime()
689: @*/
690: PetscErrorCode PETSCTS_DLLEXPORT TSSundialsSetTolerance(TS ts,double aabs,double rel)
691: {
692: PetscErrorCode ierr,(*f)(TS,double,double);
693:
695: PetscObjectQueryFunction((PetscObject)ts,"TSSundialsSetTolerance_C",(void (**)(void))&f);
696: if (f) {
697: (*f)(ts,aabs,rel);
698: }
699: return(0);
700: }
704: /*@
705: TSSundialsGetPC - Extract the PC context from a time-step context for Sundials.
707: Input Parameter:
708: . ts - the time-step context
710: Output Parameter:
711: . pc - the preconditioner context
713: Level: advanced
715: .seealso: TSSundialsGetIterations(), TSSundialsSetType(), TSSundialsSetGMRESRestart(),
716: TSSundialsSetLinearTolerance(), TSSundialsSetGramSchmidtType(), TSSundialsSetTolerance(),
717: TSSundialsGetIterations(), TSSundialsSetType(), TSSundialsSetGMRESRestart(),
718: TSSundialsSetLinearTolerance(), TSSundialsSetTolerance()
719: @*/
720: PetscErrorCode PETSCTS_DLLEXPORT TSSundialsGetPC(TS ts,PC *pc)
721: {
722: PetscErrorCode ierr,(*f)(TS,PC *);
725: PetscObjectQueryFunction((PetscObject)ts,"TSSundialsGetPC_C",(void (**)(void))&f);
726: if (f) {
727: (*f)(ts,pc);
728: } else {
729: SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"TS must be of Sundials type to extract the PC");
730: }
732: return(0);
733: }
737: /*@
738: TSSundialsSetExactFinalTime - Determines if Sundials interpolates solution to the
739: exact final time requested by the user or just returns it at the final time
740: it computed. (Defaults to true).
742: Input Parameter:
743: + ts - the time-step context
744: - ft - PETSC_TRUE if interpolates, else PETSC_FALSE
746: Level: beginner
748: .seealso:TSSundialsGetIterations(), TSSundialsSetType(), TSSundialsSetGMRESRestart(),
749: TSSundialsSetLinearTolerance(), TSSundialsSetGramSchmidtType(), TSSundialsSetTolerance(),
750: TSSundialsGetIterations(), TSSundialsSetType(), TSSundialsSetGMRESRestart(),
751: TSSundialsSetLinearTolerance(), TSSundialsSetTolerance(), TSSundialsGetPC()
752: @*/
753: PetscErrorCode PETSCTS_DLLEXPORT TSSundialsSetExactFinalTime(TS ts,PetscTruth ft)
754: {
755: PetscErrorCode ierr,(*f)(TS,PetscTruth);
758: PetscObjectQueryFunction((PetscObject)ts,"TSSundialsSetExactFinalTime_C",(void (**)(void))&f);
759: if (f) {
760: (*f)(ts,ft);
761: }
762: return(0);
763: }
765: /* -------------------------------------------------------------------------------------------*/
766: /*MC
767: TS_Sundials - ODE solver using the LLNL CVODE/SUNDIALS package (now called SUNDIALS)
769: Options Database:
770: + -ts_sundials_type <bdf,adams>
771: . -ts_sundials_gramschmidt_type <modified, classical> - type of orthogonalization inside GMRES
772: . -ts_sundials_atol <tol> - Absolute tolerance for convergence
773: . -ts_sundials_rtol <tol> - Relative tolerance for convergence
774: . -ts_sundials_linear_tolerance <tol>
775: . -ts_sundials_gmres_restart <restart> - Number of GMRES orthogonalization directions
776: - -ts_sundials_not_exact_final_time -Allow SUNDIALS to stop near the final time, not exactly on it
778: Notes: This uses its own nonlinear solver and Krylov method so PETSc SNES and KSP options do not apply
779: only PETSc PC options
781: Level: beginner
783: .seealso: TSCreate(), TS, TSSetType(), TSSundialsSetType(), TSSundialsSetGMRESRestart(), TSSundialsSetLinearTolerance(),
784: TSSundialsSetGramSchmidtType(), TSSundialsSetTolerance(), TSSundialsGetPC(), TSSundialsGetIterations(), TSSundialsSetExactFinalTime()
786: M*/
790: PetscErrorCode PETSCTS_DLLEXPORT TSCreate_Sundials(TS ts)
791: {
792: TS_Sundials *cvode;
796: ts->ops->destroy = TSDestroy_Sundials;
797: ts->ops->view = TSView_Sundials;
799: if (ts->problem_type != TS_NONLINEAR) {
800: SETERRQ(PETSC_ERR_SUP,"Only support for nonlinear problems");
801: }
802: ts->ops->setup = TSSetUp_Sundials_Nonlinear;
803: ts->ops->step = TSStep_Sundials_Nonlinear;
804: ts->ops->setfromoptions = TSSetFromOptions_Sundials_Nonlinear;
806: PetscNew(TS_Sundials,&cvode);
807: PCCreate(ts->comm,&cvode->pc);
808: PetscLogObjectParent(ts,cvode->pc);
809: ts->data = (void*)cvode;
810: cvode->cvode_type = CV_BDF;
811: cvode->gtype = SUNDIALS_UNMODIFIED_GS;
812: cvode->restart = 5;
813: cvode->linear_tol = .05;
815: cvode->exact_final_time = PETSC_FALSE;
817: MPI_Comm_dup(ts->comm,&(cvode->comm_sundials));
818: /* set tolerance for Sundials */
819: cvode->abstol = 1e-6;
820: cvode->reltol = 1e-6;
822: PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSSundialsSetType_C","TSSundialsSetType_Sundials",
823: TSSundialsSetType_Sundials);
824: PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSSundialsSetGMRESRestart_C",
825: "TSSundialsSetGMRESRestart_Sundials",
826: TSSundialsSetGMRESRestart_Sundials);
827: PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSSundialsSetLinearTolerance_C",
828: "TSSundialsSetLinearTolerance_Sundials",
829: TSSundialsSetLinearTolerance_Sundials);
830: PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSSundialsSetGramSchmidtType_C",
831: "TSSundialsSetGramSchmidtType_Sundials",
832: TSSundialsSetGramSchmidtType_Sundials);
833: PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSSundialsSetTolerance_C",
834: "TSSundialsSetTolerance_Sundials",
835: TSSundialsSetTolerance_Sundials);
836: PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSSundialsGetPC_C",
837: "TSSundialsGetPC_Sundials",
838: TSSundialsGetPC_Sundials);
839: PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSSundialsGetIterations_C",
840: "TSSundialsGetIterations_Sundials",
841: TSSundialsGetIterations_Sundials);
842: PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSSundialsSetExactFinalTime_C",
843: "TSSundialsSetExactFinalTime_Sundials",
844: TSSundialsSetExactFinalTime_Sundials);
845: return(0);
846: }