Actual source code: petscpvode.c
1: /*$Id: petscpvode.c,v 1.71 2001/08/07 03:04:23 balay Exp $*/
3: /*
4: Provides a PETSc interface to PVODE. Alan Hindmarsh's parallel ODE
5: solver.
6: */
8: #include "src/ts/impls/implicit/pvode/petscpvode.h" /*I "petscts.h" I*/
12: /*@C
13: TSPVodeGetParameters - Extract "iopt" and "ropt" PVODE parameters
15: Input Parameter:
16: . ts - the time-step context
18: Output Parameters:
19: + opt_size - size of the parameter arrays (will be set to PVODE value OPT_SIZE)
20: . iopt - the integer parameters
21: - ropt - the double paramters
24: Level: advanced
25: g
26: Notes: You may pass PETSC_NULL for any value you do not desire
28: PETSc initializes these array with the default PVODE values of 0, you may
29: change them before calling the TS solver.
31: See the PVODE include file cvode.h for the definitions of the fields
33: Suggested by: Timothy William Chevalier
35: .seealso: TSPVodeGetIterations(), TSPVodeSetType(), TSPVodeSetGMRESRestart(),
36: TSPVodeSetLinearTolerance(), TSPVodeSetGramSchmidtType(), TSPVodeSetTolerance(),
37: TSPVodeGetIterations(), TSPVodeSetType(), TSPVodeSetGMRESRestart(),
38: TSPVodeSetLinearTolerance(), TSPVodeSetTolerance()
39: @*/
40: int TSPVodeGetParameters(TS ts,int *opt_size,long int *iopt[],double *ropt[])
41: {
42: TS_PVode *cvode = (TS_PVode*)ts->data;
45: if (opt_size) *opt_size = OPT_SIZE;
46: if (iopt) *iopt = cvode->iopt;
47: if (ropt) *ropt = cvode->ropt;
48: return(0);
49: }
51: /*
52: TSPrecond_PVode - function that we provide to PVODE to
53: evaluate the preconditioner.
55: Contributed by: Liyang Xu
57: */
60: int TSPrecond_PVode(integertype N,realtype tn,N_Vector y,N_Vector fy,booleantype jok,
61: booleantype *jcurPtr,realtype _gamma,N_Vector ewt,realtype h,
62: realtype uround,long int *nfePtr,void *P_data,
63: N_Vector vtemp1,N_Vector vtemp2,N_Vector vtemp3)
64: {
65: TS ts = (TS) P_data;
66: TS_PVode *cvode = (TS_PVode*)ts->data;
67: PC pc = cvode->pc;
68: int ierr;
69: Mat Jac = ts->B;
70: Vec tmpy = cvode->w1;
71: PetscScalar one = 1.0,gm;
72: MatStructure str = DIFFERENT_NONZERO_PATTERN;
73:
75: /* This allows us to construct preconditioners in-place if we like */
76: MatSetUnfactored(Jac);
78: /*
79: jok - TRUE means reuse current Jacobian else recompute Jacobian
80: */
81: if (jok) {
82: MatCopy(cvode->pmat,Jac,SAME_NONZERO_PATTERN);
83: str = SAME_NONZERO_PATTERN;
84: *jcurPtr = FALSE;
85: } else {
86: /* make PETSc vector tmpy point to PVODE vector y */
87: VecPlaceArray(tmpy,N_VGetData(y));
89: /* compute the Jacobian */
90: TSComputeRHSJacobian(ts,ts->ptime,tmpy,&Jac,&Jac,&str);
92: /* copy the Jacobian matrix */
93: if (!cvode->pmat) {
94: MatDuplicate(Jac,MAT_COPY_VALUES,&cvode->pmat);
95: PetscLogObjectParent(ts,cvode->pmat);
96: }
97: MatCopy(Jac,cvode->pmat,SAME_NONZERO_PATTERN);
99: *jcurPtr = TRUE;
100: }
102: /* construct I-gamma*Jac */
103: gm = -_gamma;
104: MatScale(&gm,Jac);
105: MatShift(&one,Jac);
106:
107: PCSetOperators(pc,Jac,Jac,str);
108: return(0);
109: }
111: /*
112: TSPSolve_PVode - routine that we provide to PVode that applies the preconditioner.
113:
114: Contributed by: Liyang Xu
116: */
119: int TSPSolve_PVode(integertype N,realtype tn,N_Vector y,N_Vector fy,N_Vector vtemp,
120: realtype _gamma,N_Vector ewt,realtype delta,long int *nfePtr,
121: N_Vector r,int lr,void *P_data,N_Vector z)
122: {
123: TS ts = (TS) P_data;
124: TS_PVode *cvode = (TS_PVode*)ts->data;
125: PC pc = cvode->pc;
126: Vec rr = cvode->w1,xx = cvode->w2;
127: int ierr;
130: /*
131: Make the PETSc work vectors rr and xx point to the arrays in the PVODE vectors
132: */
133: VecPlaceArray(rr,N_VGetData(r));
134: VecPlaceArray(xx,N_VGetData(z));
136: /*
137: Solve the Px=r and put the result in xx
138: */
139: PCApply(pc,rr,xx,PC_LEFT);
140: cvode->linear_solves++;
143: return(0);
144: }
146: /*
147: TSFunction_PVode - routine that we provide to PVode that applies the right hand side.
148:
149: Contributed by: Liyang Xu
150: */
153: void TSFunction_PVode(int N,double t,N_Vector y,N_Vector ydot,void *ctx)
154: {
155: TS ts = (TS) ctx;
156: TS_PVode *cvode = (TS_PVode*)ts->data;
157: Vec tmpx = cvode->w1,tmpy = cvode->w2;
158: int ierr;
161: /*
162: Make the PETSc work vectors tmpx and tmpy point to the arrays in the PVODE vectors
163: */
164: VecPlaceArray(tmpx,N_VGetData(y));
165: if (ierr) {
166: (*PetscErrorPrintf)("TSFunction_PVode:Could not place array. Error code %d",ierr);
167: }
168: VecPlaceArray(tmpy,N_VGetData(ydot));
169: if (ierr) {
170: (*PetscErrorPrintf)("TSFunction_PVode:Could not place array. Error code %d",ierr);
171: }
173: /* now compute the right hand side function */
174: TSComputeRHSFunction(ts,t,tmpx,tmpy);
175: if (ierr) {
176: (*PetscErrorPrintf)("TSFunction_PVode:Could not compute RHS function. Error code %d",ierr);
177: }
178: }
180: /*
181: TSStep_PVode_Nonlinear - Calls PVode to integrate the ODE.
183: Contributed by: Liyang Xu
184: */
187: /*
188: TSStep_PVode_Nonlinear -
189:
190: steps - number of time steps
191: time - time that integrater is terminated.
193: */
194: int TSStep_PVode_Nonlinear(TS ts,int *steps,double *time)
195: {
196: TS_PVode *cvode = (TS_PVode*)ts->data;
197: Vec sol = ts->vec_sol;
198: int ierr,i,max_steps = ts->max_steps,flag;
199: double t,tout;
200: realtype *tmp;
203: /* initialize the number of steps */
204: *steps = -ts->steps;
205: TSMonitor(ts,ts->steps,ts->ptime,sol);
207: /* call CVSpgmr to use GMRES as the linear solver. */
208: /* setup the ode integrator with the given preconditioner */
209: CVSpgmr(cvode->mem,LEFT,cvode->gtype,cvode->restart,cvode->linear_tol,TSPrecond_PVode,TSPSolve_PVode,ts,0,0);
211: tout = ts->max_time;
212: for (i=0; i<max_steps; i++) {
213: if (ts->ptime >= tout) break;
214: VecGetArray(ts->vec_sol,&tmp);
215: N_VSetData(tmp,cvode->y);
216: flag = CVode(cvode->mem,tout,cvode->y,&t,ONE_STEP);
217: cvode->nonlinear_solves += cvode->iopt[NNI];
218: VecRestoreArray(ts->vec_sol,PETSC_NULL);
219: if (flag != SUCCESS) SETERRQ(PETSC_ERR_LIB,"PVODE failed");
221: if (t > tout && cvode->exact_final_time) {
222: /* interpolate to final requested time */
223: VecGetArray(ts->vec_sol,&tmp);
224: N_VSetData(tmp,cvode->y);
225: flag = CVodeDky(cvode->mem,tout,0,cvode->y);
226: VecRestoreArray(ts->vec_sol,PETSC_NULL);
227: if (flag != SUCCESS) SETERRQ(PETSC_ERR_LIB,"PVODE interpolation to final time failed");
228: t = tout;
229: }
231: ts->time_step = t - ts->ptime;
232: ts->ptime = t;
234: /*
235: copy the solution from cvode->y to cvode->update and sol
236: */
237: VecPlaceArray(cvode->w1,N_VGetData(cvode->y));
238: VecCopy(cvode->w1,cvode->update);
239: VecCopy(cvode->update,sol);
240:
241: ts->steps++;
242: TSMonitor(ts,ts->steps,t,sol);
243: ts->nonlinear_its = cvode->iopt[NNI];
244: ts->linear_its = cvode->iopt[SPGMR_NLI];
245: }
247: *steps += ts->steps;
248: *time = t;
250: return(0);
251: }
253: /*
255: Contributed by: Liyang Xu
256: */
259: int TSDestroy_PVode(TS ts)
260: {
261: TS_PVode *cvode = (TS_PVode*)ts->data;
262: int ierr;
265: if (cvode->pmat) {MatDestroy(cvode->pmat);}
266: if (cvode->pc) {PCDestroy(cvode->pc);}
267: if (cvode->update) {VecDestroy(cvode->update);}
268: if (cvode->func) {VecDestroy(cvode->func);}
269: if (cvode->rhs) {VecDestroy(cvode->rhs);}
270: if (cvode->w1) {VecDestroy(cvode->w1);}
271: if (cvode->w2) {VecDestroy(cvode->w2);}
272: MPI_Comm_free(&(cvode->comm_pvode));
273: PetscFree(cvode);
274: return(0);
275: }
277: /*
279: Contributed by: Liyang Xu
280: */
283: int TSSetUp_PVode_Nonlinear(TS ts)
284: {
285: TS_PVode *cvode = (TS_PVode*)ts->data;
286: int ierr,M,locsize;
287: M_Env machEnv;
288: realtype *tmp;
291: PCSetFromOptions(cvode->pc);
292: /* get the vector size */
293: VecGetSize(ts->vec_sol,&M);
294: VecGetLocalSize(ts->vec_sol,&locsize);
296: /* allocate the memory for machEnv */
297: /* machEnv = PVInitMPI(cvode->>comm_pvode,locsize,M); */
298: machEnv = M_EnvInit_Parallel(cvode->comm_pvode, locsize, M, 0, 0);
301: /* allocate the memory for N_Vec y */
302: cvode->y = N_VNew(M,machEnv);
303: VecGetArray(ts->vec_sol,&tmp);
304: N_VSetData(tmp,cvode->y);
305: VecRestoreArray(ts->vec_sol,PETSC_NULL);
307: /* initializing vector update and func */
308: VecDuplicate(ts->vec_sol,&cvode->update);
309: VecDuplicate(ts->vec_sol,&cvode->func);
310: PetscLogObjectParent(ts,cvode->update);
311: PetscLogObjectParent(ts,cvode->func);
313: /*
314: Create work vectors for the TSPSolve_PVode() routine. Note these are
315: allocated with zero space arrays because the actual array space is provided
316: by PVode and set using VecPlaceArray().
317: */
318: VecCreateMPIWithArray(ts->comm,locsize,PETSC_DECIDE,0,&cvode->w1);
319: VecCreateMPIWithArray(ts->comm,locsize,PETSC_DECIDE,0,&cvode->w2);
320: PetscLogObjectParent(ts,cvode->w1);
321: PetscLogObjectParent(ts,cvode->w2);
323: PCSetVector(cvode->pc,ts->vec_sol);
325: /* allocate memory for PVode */
326: VecGetArray(ts->vec_sol,&tmp);
327: N_VSetData(tmp,cvode->y);
328: cvode->mem = CVodeMalloc(M,TSFunction_PVode,ts->ptime,cvode->y,cvode->cvode_type,
329: NEWTON,SS,&cvode->reltol,&cvode->abstol,ts,NULL,TRUE,cvode->iopt,
330: cvode->ropt,machEnv);
331: VecRestoreArray(ts->vec_sol,PETSC_NULL);
332: return(0);
333: }
335: /*
337: Contributed by: Liyang Xu
338: */
341: int TSSetFromOptions_PVode_Nonlinear(TS ts)
342: {
343: TS_PVode *cvode = (TS_PVode*)ts->data;
344: int ierr,indx;
345: const char *btype[] = {"bdf","adams"},*otype[] = {"modified","unmodified"};
346: PetscTruth flag;
349: PetscOptionsHead("PVODE ODE solver options");
350: PetscOptionsEList("-ts_pvode_type","Scheme","TSPVodeSetType",btype,2,"bdf",&indx,&flag);
351: if (flag) {
352: TSPVodeSetType(ts,(TSPVodeType)indx);
353: }
354: PetscOptionsEList("-ts_pvode_gramschmidt_type","Type of orthogonalization","TSPVodeSetGramSchmidtType",otype,2,"unmodified",&indx,&flag);
355: if (flag) {
356: TSPVodeSetGramSchmidtType(ts,(TSPVodeGramSchmidtType)indx);
357: }
358: PetscOptionsReal("-ts_pvode_atol","Absolute tolerance for convergence","TSPVodeSetTolerance",cvode->abstol,&cvode->abstol,PETSC_NULL);
359: PetscOptionsReal("-ts_pvode_rtol","Relative tolerance for convergence","TSPVodeSetTolerance",cvode->reltol,&cvode->reltol,PETSC_NULL);
360: PetscOptionsReal("-ts_pvode_linear_tolerance","Convergence tolerance for linear solve","TSPVodeSetLinearTolerance",cvode->linear_tol,&cvode->linear_tol,&flag);
361: PetscOptionsInt("-ts_pvode_gmres_restart","Number of GMRES orthogonalization directions","TSPVodeSetGMRESRestart",cvode->restart,&cvode->restart,&flag);
362: PetscOptionsName("-ts_pvode_not_exact_final_time","Allow PVODE to stop near the final time, not exactly on it","TSPVodeSetExactFinalTime",&cvode->exact_final_time);
363: PetscOptionsTail();
365: return(0);
366: }
368: /*
370: Contributed by: Liyang Xu
371: */
374: int TSPrintHelp_PVode(TS ts,char *p)
375: {
376: int ierr;
379: (*PetscHelpPrintf)(ts->comm," Options for TSPVODE integrater:\n");
380: (*PetscHelpPrintf)(ts->comm," -ts_pvode_type <bdf,adams>: integration approach\n",p);
381: (*PetscHelpPrintf)(ts->comm," -ts_pvode_atol aabs: absolute tolerance of ODE solution\n",p);
382: (*PetscHelpPrintf)(ts->comm," -ts_pvode_rtol rel: relative tolerance of ODE solution\n",p);
383: (*PetscHelpPrintf)(ts->comm," -ts_pvode_gramschmidt_type <unmodified,modified>\n");
384: (*PetscHelpPrintf)(ts->comm," -ts_pvode_gmres_restart <restart_size> (also max. GMRES its)\n");
385: (*PetscHelpPrintf)(ts->comm," -ts_pvode_linear_tolerance <tol>\n");
386: (*PetscHelpPrintf)(ts->comm," -ts_pvode_not_exact_final_time\n");
388: return(0);
389: }
391: /*
393: Contributed by: Liyang Xu
394: */
397: int TSView_PVode(TS ts,PetscViewer viewer)
398: {
399: TS_PVode *cvode = (TS_PVode*)ts->data;
400: int ierr;
401: char *type;
402: PetscTruth isascii,isstring;
405: if (cvode->cvode_type == PVODE_ADAMS) {type = "Adams";}
406: else {type = "BDF: backward differentiation formula";}
408: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
409: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_STRING,&isstring);
410: if (isascii) {
411: PetscViewerASCIIPrintf(viewer,"PVode integrater does not use SNES!\n");
412: PetscViewerASCIIPrintf(viewer,"PVode integrater type %s\n",type);
413: PetscViewerASCIIPrintf(viewer,"PVode abs tol %g rel tol %g\n",cvode->abstol,cvode->reltol);
414: PetscViewerASCIIPrintf(viewer,"PVode linear solver tolerance factor %g\n",cvode->linear_tol);
415: PetscViewerASCIIPrintf(viewer,"PVode GMRES max iterations (same as restart in PVODE) %d\n",cvode->restart);
416: if (cvode->gtype == PVODE_MODIFIED_GS) {
417: PetscViewerASCIIPrintf(viewer,"PVode using modified Gram-Schmidt for orthogonalization in GMRES\n");
418: } else {
419: PetscViewerASCIIPrintf(viewer,"PVode using unmodified (classical) Gram-Schmidt for orthogonalization in GMRES\n");
420: }
421: } else if (isstring) {
422: PetscViewerStringSPrintf(viewer,"Pvode type %s",type);
423: } else {
424: SETERRQ1(1,"Viewer type %s not supported by TS PVode",((PetscObject)viewer)->type_name);
425: }
426: PetscViewerASCIIPushTab(viewer);
427: PCView(cvode->pc,viewer);
428: PetscViewerASCIIPopTab(viewer);
430: return(0);
431: }
434: /* --------------------------------------------------------------------------*/
435: EXTERN_C_BEGIN
438: int TSPVodeSetType_PVode(TS ts,TSPVodeType type)
439: {
440: TS_PVode *cvode = (TS_PVode*)ts->data;
441:
443: cvode->cvode_type = type;
444: return(0);
445: }
446: EXTERN_C_END
448: EXTERN_C_BEGIN
451: int TSPVodeSetGMRESRestart_PVode(TS ts,int restart)
452: {
453: TS_PVode *cvode = (TS_PVode*)ts->data;
454:
456: cvode->restart = restart;
457: return(0);
458: }
459: EXTERN_C_END
461: EXTERN_C_BEGIN
464: int TSPVodeSetLinearTolerance_PVode(TS ts,double tol)
465: {
466: TS_PVode *cvode = (TS_PVode*)ts->data;
467:
469: cvode->linear_tol = tol;
470: return(0);
471: }
472: EXTERN_C_END
474: EXTERN_C_BEGIN
477: int TSPVodeSetGramSchmidtType_PVode(TS ts,TSPVodeGramSchmidtType type)
478: {
479: TS_PVode *cvode = (TS_PVode*)ts->data;
480:
482: cvode->gtype = type;
484: return(0);
485: }
486: EXTERN_C_END
488: EXTERN_C_BEGIN
491: int TSPVodeSetTolerance_PVode(TS ts,double aabs,double rel)
492: {
493: TS_PVode *cvode = (TS_PVode*)ts->data;
494:
496: if (aabs != PETSC_DECIDE) cvode->abstol = aabs;
497: if (rel != PETSC_DECIDE) cvode->reltol = rel;
498: return(0);
499: }
500: EXTERN_C_END
502: EXTERN_C_BEGIN
505: int TSPVodeGetPC_PVode(TS ts,PC *pc)
506: {
507: TS_PVode *cvode = (TS_PVode*)ts->data;
510: *pc = cvode->pc;
512: return(0);
513: }
514: EXTERN_C_END
516: EXTERN_C_BEGIN
519: int TSPVodeGetIterations_PVode(TS ts,int *nonlin,int *lin)
520: {
521: TS_PVode *cvode = (TS_PVode*)ts->data;
522:
524: if (nonlin) *nonlin = cvode->nonlinear_solves;
525: if (lin) *lin = cvode->linear_solves;
526: return(0);
527: }
528: EXTERN_C_END
529:
530: EXTERN_C_BEGIN
533: int TSPVodeSetExactFinalTime_PVode(TS ts,PetscTruth s)
534: {
535: TS_PVode *cvode = (TS_PVode*)ts->data;
536:
538: cvode->exact_final_time = s;
539: return(0);
540: }
541: EXTERN_C_END
542: /* -------------------------------------------------------------------------------------------*/
546: /*@C
547: TSPVodeGetIterations - Gets the number of nonlinear and linear iterations used so far by PVode.
549: Not Collective
551: Input parameters:
552: . ts - the time-step context
554: Output Parameters:
555: + nonlin - number of nonlinear iterations
556: - lin - number of linear iterations
558: Level: advanced
560: Notes:
561: These return the number since the creation of the TS object
563: .keywords: non-linear iterations, linear iterations
565: .seealso: TSPVodeSetType(), TSPVodeSetGMRESRestart(),
566: TSPVodeSetLinearTolerance(), TSPVodeSetGramSchmidtType(), TSPVodeSetTolerance(),
567: TSPVodeGetIterations(), TSPVodeSetType(), TSPVodeSetGMRESRestart(),
568: TSPVodeSetLinearTolerance(), TSPVodeSetTolerance(), TSPVodeGetPC(),
569: TSPVodeSetExactFinalTime()
571: @*/
572: int TSPVodeGetIterations(TS ts,int *nonlin,int *lin)
573: {
574: int ierr,(*f)(TS,int*,int*);
575:
577: PetscObjectQueryFunction((PetscObject)ts,"TSPVodeGetIterations_C",(void (**)(void))&f);
578: if (f) {
579: (*f)(ts,nonlin,lin);
580: }
581: return(0);
582: }
586: /*@
587: TSPVodeSetType - Sets the method that PVode will use for integration.
589: Collective on TS
591: Input parameters:
592: + ts - the time-step context
593: - type - one of PVODE_ADAMS or PVODE_BDF
595: Contributed by: Liyang Xu
597: Level: intermediate
599: .keywords: Adams, backward differentiation formula
601: .seealso: TSPVodeGetIterations(), TSPVodeSetGMRESRestart(),
602: TSPVodeSetLinearTolerance(), TSPVodeSetGramSchmidtType(), TSPVodeSetTolerance(),
603: TSPVodeGetIterations(), TSPVodeSetType(), TSPVodeSetGMRESRestart(),
604: TSPVodeSetLinearTolerance(), TSPVodeSetTolerance(), TSPVodeGetPC(),
605: TSPVodeSetExactFinalTime()
606: @*/
607: int TSPVodeSetType(TS ts,TSPVodeType type)
608: {
609: int ierr,(*f)(TS,TSPVodeType);
610:
612: PetscObjectQueryFunction((PetscObject)ts,"TSPVodeSetType_C",(void (**)(void))&f);
613: if (f) {
614: (*f)(ts,type);
615: }
616: return(0);
617: }
621: /*@
622: TSPVodeSetGMRESRestart - Sets the dimension of the Krylov space used by
623: GMRES in the linear solver in PVODE. PVODE DOES NOT use restarted GMRES so
624: this is ALSO the maximum number of GMRES steps that will be used.
626: Collective on TS
628: Input parameters:
629: + ts - the time-step context
630: - restart - number of direction vectors (the restart size).
632: Level: advanced
634: .keywords: GMRES, restart
636: .seealso: TSPVodeGetIterations(), TSPVodeSetType(),
637: TSPVodeSetLinearTolerance(), TSPVodeSetGramSchmidtType(), TSPVodeSetTolerance(),
638: TSPVodeGetIterations(), TSPVodeSetType(), TSPVodeSetGMRESRestart(),
639: TSPVodeSetLinearTolerance(), TSPVodeSetTolerance(), TSPVodeGetPC(),
640: TSPVodeSetExactFinalTime()
642: @*/
643: int TSPVodeSetGMRESRestart(TS ts,int restart)
644: {
645: int ierr,(*f)(TS,int);
648: PetscObjectQueryFunction((PetscObject)ts,"TSPVodeSetGMRESRestart_C",(void (**)(void))&f);
649: if (f) {
650: (*f)(ts,restart);
651: }
653: return(0);
654: }
658: /*@
659: TSPVodeSetLinearTolerance - Sets the tolerance used to solve the linear
660: system by PVODE.
662: Collective on TS
664: Input parameters:
665: + ts - the time-step context
666: - tol - the factor by which the tolerance on the nonlinear solver is
667: multiplied to get the tolerance on the linear solver, .05 by default.
669: Level: advanced
671: .keywords: GMRES, linear convergence tolerance, PVODE
673: .seealso: TSPVodeGetIterations(), TSPVodeSetType(), TSPVodeSetGMRESRestart(),
674: TSPVodeSetGramSchmidtType(), TSPVodeSetTolerance(),
675: TSPVodeGetIterations(), TSPVodeSetType(), TSPVodeSetGMRESRestart(),
676: TSPVodeSetLinearTolerance(), TSPVodeSetTolerance(), TSPVodeGetPC(),
677: TSPVodeSetExactFinalTime()
679: @*/
680: int TSPVodeSetLinearTolerance(TS ts,double tol)
681: {
682: int ierr,(*f)(TS,double);
683:
685: PetscObjectQueryFunction((PetscObject)ts,"TSPVodeSetLinearTolerance_C",(void (**)(void))&f);
686: if (f) {
687: (*f)(ts,tol);
688: }
689: return(0);
690: }
694: /*@
695: TSPVodeSetGramSchmidtType - Sets type of orthogonalization used
696: in GMRES method by PVODE linear solver.
698: Collective on TS
700: Input parameters:
701: + ts - the time-step context
702: - type - either PVODE_MODIFIED_GS or PVODE_CLASSICAL_GS
704: Level: advanced
706: .keywords: PVode, orthogonalization
708: .seealso: TSPVodeGetIterations(), TSPVodeSetType(), TSPVodeSetGMRESRestart(),
709: TSPVodeSetLinearTolerance(), TSPVodeSetTolerance(),
710: TSPVodeGetIterations(), TSPVodeSetType(), TSPVodeSetGMRESRestart(),
711: TSPVodeSetLinearTolerance(), TSPVodeSetTolerance(), TSPVodeGetPC(),
712: TSPVodeSetExactFinalTime()
714: @*/
715: int TSPVodeSetGramSchmidtType(TS ts,TSPVodeGramSchmidtType type)
716: {
717: int ierr,(*f)(TS,TSPVodeGramSchmidtType);
718:
720: PetscObjectQueryFunction((PetscObject)ts,"TSPVodeSetGramSchmidtType_C",(void (**)(void))&f);
721: if (f) {
722: (*f)(ts,type);
723: }
724: return(0);
725: }
729: /*@
730: TSPVodeSetTolerance - Sets the absolute and relative tolerance used by
731: PVode for error control.
733: Collective on TS
735: Input parameters:
736: + ts - the time-step context
737: . aabs - the absolute tolerance
738: - rel - the relative tolerance
740: Contributed by: Liyang Xu
742: See the Cvode/Pvode users manual for exact details on these parameters. Essentially
743: these regulate the size of the error for a SINGLE timestep.
745: Level: intermediate
747: .keywords: PVode, tolerance
749: .seealso: TSPVodeGetIterations(), TSPVodeSetType(), TSPVodeSetGMRESRestart(),
750: TSPVodeSetLinearTolerance(), TSPVodeSetGramSchmidtType(),
751: TSPVodeGetIterations(), TSPVodeSetType(), TSPVodeSetGMRESRestart(),
752: TSPVodeSetLinearTolerance(), TSPVodeSetTolerance(), TSPVodeGetPC(),
753: TSPVodeSetExactFinalTime()
755: @*/
756: int TSPVodeSetTolerance(TS ts,double aabs,double rel)
757: {
758: int ierr,(*f)(TS,double,double);
759:
761: PetscObjectQueryFunction((PetscObject)ts,"TSPVodeSetTolerance_C",(void (**)(void))&f);
762: if (f) {
763: (*f)(ts,aabs,rel);
764: }
765: return(0);
766: }
770: /*@
771: TSPVodeGetPC - Extract the PC context from a time-step context for PVode.
773: Input Parameter:
774: . ts - the time-step context
776: Output Parameter:
777: . pc - the preconditioner context
779: Level: advanced
781: Contributed by: Liyang Xu
783: .seealso: TSPVodeGetIterations(), TSPVodeSetType(), TSPVodeSetGMRESRestart(),
784: TSPVodeSetLinearTolerance(), TSPVodeSetGramSchmidtType(), TSPVodeSetTolerance(),
785: TSPVodeGetIterations(), TSPVodeSetType(), TSPVodeSetGMRESRestart(),
786: TSPVodeSetLinearTolerance(), TSPVodeSetTolerance()
787: @*/
788: int TSPVodeGetPC(TS ts,PC *pc)
789: {
790: int ierr,(*f)(TS,PC *);
793: PetscObjectQueryFunction((PetscObject)ts,"TSPVodeGetPC_C",(void (**)(void))&f);
794: if (f) {
795: (*f)(ts,pc);
796: } else {
797: SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"TS must be of PVode type to extract the PC");
798: }
800: return(0);
801: }
805: /*@
806: TSPVodeSetExactFinalTime - Determines if PVode interpolates solution to the
807: exact final time requested by the user or just returns it at the final time
808: it computed. (Defaults to true).
810: Input Parameter:
811: + ts - the time-step context
812: - ft - PETSC_TRUE if interpolates, else PETSC_FALSE
814: Level: beginner
816: .seealso:TSPVodeGetIterations(), TSPVodeSetType(), TSPVodeSetGMRESRestart(),
817: TSPVodeSetLinearTolerance(), TSPVodeSetGramSchmidtType(), TSPVodeSetTolerance(),
818: TSPVodeGetIterations(), TSPVodeSetType(), TSPVodeSetGMRESRestart(),
819: TSPVodeSetLinearTolerance(), TSPVodeSetTolerance(), TSPVodeGetPC()
820: @*/
821: int TSPVodeSetExactFinalTime(TS ts,PetscTruth ft)
822: {
823: int ierr,(*f)(TS,PetscTruth);
826: PetscObjectQueryFunction((PetscObject)ts,"TSPVodeSetExactFinalTime_C",(void (**)(void))&f);
827: if (f) {
828: (*f)(ts,ft);
829: }
831: return(0);
832: }
834: /* -------------------------------------------------------------------------------------------*/
835: /*MC
836: TS_PVode - ODE solver using the LLNL CVODE/PVODE package (now called SUNDIALS)
838: Options Database:
839: + -ts_pvode_type <bdf,adams>
840: . -ts_pvode_gramschmidt_type <modified, classical> - type of orthogonalization inside GMRES
841: . -ts_pvode_atol <tol> - Absolute tolerance for convergence
842: . -ts_pvode_rtol <tol> - Relative tolerance for convergence
843: . -ts_pvode_linear_tolerance <tol>
844: . -ts_pvode_gmres_restart <restart> - Number of GMRES orthogonalization directions
845: - -ts_pvode_not_exact_final_time -Allow PVODE to stop near the final time, not exactly on it
847: Notes: This uses its own nonlinear solver and Krylov method so PETSc SNES and KSP options do not apply
848: only PETSc PC options
850: Contributed by: Liyang Xu
852: .seealso: TSCreate(), TS, TSSetType(), TSPVodeSetType(), TSPVodeSetGMRESRestart(), TSPVodeSetLinearTolerance(),
853: TSPVodeSetGramSchmidtType(), TSPVodeSetTolerance(), TSPVodeGetPC(), TSPVodeGetIterations(), TSPVodeSetExactFinalTime()
855: M*/
856: EXTERN_C_BEGIN
859: int TSCreate_PVode(TS ts)
860: {
861: TS_PVode *cvode;
862: int ierr;
865: ts->ops->destroy = TSDestroy_PVode;
866: ts->ops->view = TSView_PVode;
868: if (ts->problem_type != TS_NONLINEAR) {
869: SETERRQ(PETSC_ERR_SUP,"Only support for nonlinear problems");
870: }
871: ts->ops->setup = TSSetUp_PVode_Nonlinear;
872: ts->ops->step = TSStep_PVode_Nonlinear;
873: ts->ops->setfromoptions = TSSetFromOptions_PVode_Nonlinear;
875: PetscNew(TS_PVode,&cvode);
876: PetscMemzero(cvode,sizeof(TS_PVode));
877: PCCreate(ts->comm,&cvode->pc);
878: PetscLogObjectParent(ts,cvode->pc);
879: ts->data = (void*)cvode;
880: cvode->cvode_type = BDF;
881: cvode->gtype = PVODE_UNMODIFIED_GS;
882: cvode->restart = 5;
883: cvode->linear_tol = .05;
885: cvode->exact_final_time = PETSC_TRUE;
887: MPI_Comm_dup(ts->comm,&(cvode->comm_pvode));
888: /* set tolerance for PVode */
889: cvode->abstol = 1e-6;
890: cvode->reltol = 1e-6;
892: PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSPVodeSetType_C","TSPVodeSetType_PVode",
893: TSPVodeSetType_PVode);
894: PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSPVodeSetGMRESRestart_C",
895: "TSPVodeSetGMRESRestart_PVode",
896: TSPVodeSetGMRESRestart_PVode);
897: PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSPVodeSetLinearTolerance_C",
898: "TSPVodeSetLinearTolerance_PVode",
899: TSPVodeSetLinearTolerance_PVode);
900: PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSPVodeSetGramSchmidtType_C",
901: "TSPVodeSetGramSchmidtType_PVode",
902: TSPVodeSetGramSchmidtType_PVode);
903: PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSPVodeSetTolerance_C",
904: "TSPVodeSetTolerance_PVode",
905: TSPVodeSetTolerance_PVode);
906: PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSPVodeGetPC_C",
907: "TSPVodeGetPC_PVode",
908: TSPVodeGetPC_PVode);
909: PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSPVodeGetIterations_C",
910: "TSPVodeGetIterations_PVode",
911: TSPVodeGetIterations_PVode);
912: PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSPVodeSetExactFinalTime_C",
913: "TSPVodeSetExactFinalTime_PVode",
914: TSPVodeSetExactFinalTime_PVode);
915: return(0);
916: }
917: EXTERN_C_END