Close
#include <stdio.h>
#include
#include
#include
#define Ith(v,i) NV_Ith_S(v,i-1)
#define RHS1 1
#define RHS2 2
static int f(realtype t, N_Vector y, N_Vector ydot, void *f_data);
int main()
{
void *cvode_mem;
N_Vector y;
int neq, flag;
realtype reltol, abstol, t0, t1, t2, t;
long int nst1, nst2, nst;
neq = 1;
reltol = RCONST(1.0e-3);
abstol = RCONST(1.0e-4);
t0 = RCONST(0.0);
t1 = RCONST(1.0);
t2 = RCONST(2.0);
y = N_VNew_Serial(neq);
printf("\nDiscontinuity in solution\n\n");
cvode_mem = CVodeCreate(CV_BDF, CV_NEWTON);
Ith(y,1) = 1.0;
CVodeMalloc(cvode_mem, f, t0, y, CV_SS, reltol, &abstol);
CVodeSetFdata(cvode_mem, &flag);
CVDense(cvode_mem, neq);
CVodeSetStopTime(cvode_mem, t1);
flag = RHS1;
t = t0;
printf("%12.8e %12.8e\n",t,Ith(y,1));
while (t<t1) {
CVode(cvode_mem, t1, y, &t, CV_ONE_STEP_TSTOP);
printf("%12.8e %12.8e\n",t,Ith(y,1));
}
CVodeGetNumSteps(cvode_mem, &nst1);
Ith(y,1) = 1.0;
CVodeReInit(cvode_mem, f, t1, y, CV_SS, reltol, &abstol);
CVodeSetStopTime(cvode_mem, t2);
flag = RHS1;
t = t1;
printf("%12.8e %12.8e\n",t,Ith(y,1));
while (t<t2) {
CVode(cvode_mem, t2, y, &t, CV_ONE_STEP_TSTOP);
printf("%12.8e %12.8e\n",t,Ith(y,1));
}
CVodeGetNumSteps(cvode_mem, &nst2);
nst = nst1 + nst2;
printf("\nNumber of steps: %ld + %ld = %ld\n",nst1, nst2, nst);
CVodeFree(&cvode_mem);
printf("\nDiscontinuity in RHS: Case 1 - explicit treatment\n\n");
cvode_mem = CVodeCreate(CV_BDF, CV_NEWTON);
Ith(y,1) = 1.0;
CVodeMalloc(cvode_mem, f, t0, y, CV_SS, reltol, &abstol);
CVodeSetFdata(cvode_mem, &flag);
CVDense(cvode_mem, neq);
CVodeSetStopTime(cvode_mem, t1);
flag = RHS1;
t = t0;
printf("%12.8e %12.8e\n",t,Ith(y,1));
while (t<t1) {
CVode(cvode_mem, t1, y, &t, CV_ONE_STEP_TSTOP);
printf("%12.8e %12.8e\n",t,Ith(y,1));
}
CVodeGetNumSteps(cvode_mem, &nst1);
CVodeReInit(cvode_mem, f, t1, y, CV_SS, reltol, &abstol);
CVodeSetStopTime(cvode_mem, t2);
flag = RHS2;
t = t1;
printf("%12.8e %12.8e\n",t,Ith(y,1));
while (t<t2) {
CVode(cvode_mem, t2, y, &t, CV_ONE_STEP_TSTOP);
printf("%12.8e %12.8e\n",t,Ith(y,1));
}
CVodeGetNumSteps(cvode_mem, &nst2);
nst = nst1 + nst2;
printf("\nNumber of steps: %ld + %ld = %ld\n",nst1, nst2, nst);
CVodeFree(&cvode_mem);
printf("\nDiscontinuity in RHS: Case 2 - let CVODES deal with it\n\n");
cvode_mem = CVodeCreate(CV_BDF, CV_NEWTON);
Ith(y,1) = 1.0;
CVodeMalloc(cvode_mem, f, t0, y, CV_SS, reltol, &abstol);
CVodeSetFdata(cvode_mem, &flag);
CVDense(cvode_mem, neq);
CVodeSetStopTime(cvode_mem, t1);
flag = RHS1;
t = t0;
printf("%12.8e %12.8e\n",t,Ith(y,1));
while (t<t1) {
CVode(cvode_mem, t1, y, &t, CV_ONE_STEP_TSTOP);
printf("%12.8e %12.8e\n",t,Ith(y,1));
}
CVodeGetNumSteps(cvode_mem, &nst1);
CVodeSetStopTime(cvode_mem, t2);
flag = RHS2;
t = t1;
printf("%12.8e %12.8e\n",t,Ith(y,1));
while (t<t2) {
CVode(cvode_mem, t2, y, &t, CV_ONE_STEP_TSTOP);
printf("%12.8e %12.8e\n",t,Ith(y,1));
}
CVodeGetNumSteps(cvode_mem, &nst);
nst2 = nst - nst1;
printf("\nNumber of steps: %ld + %ld = %ld\n",nst1, nst2, nst);
CVodeFree(&cvode_mem);
N_VDestroy(y);
return(0);
}
static int f(realtype t, N_Vector y, N_Vector ydot, void *f_data)
{
int *flag;
flag = (int *) f_data;
switch(*flag) {
case RHS1:
Ith(ydot,1) = -Ith(y,1);
break;
case RHS2:
Ith(ydot,1) = -5.0*Ith(y,1);
break;
}
return(0);
}
Close