int main() { void *cpode_mem; N_Vector yy, yp, ctols; realtype reltol, abstol, t, tout, Tout; realtype x, y, xd, yd, g; int iout, Nout, flag; printf("double %d\n",(int)sizeof(double)); printf("long double %d\n",(int)sizeof(long double)); printf("float %d\n",(int)sizeof(float)); printf("realtype %d\n",(int)sizeof(realtype)); yy = N_VNew_Serial(4); yp = N_VNew_Serial(4); /* Initialize y */ Ith(yy,1) = 1.0; /* x */ Ith(yy,2) = 0.0; /* y */ Ith(yy,3) = 0.0; /* xd */ Ith(yy,4) = 0.0; /* yd */ /* Set tolerances */ reltol = RTOL; abstol = ATOL; Nout = 30; Tout = Nout*1.0; /* Initialize solver */ cpode_mem = CPodeCreate(CP_EXPL, CP_BDF, CP_NEWTON); flag = CPodeInit(cpode_mem, f, NULL, 0.0, yy, yp, CP_SS, reltol, &abstol); flag = CPodeSetMaxNumSteps(cpode_mem, 5000); flag = CPodeSetStopTime(cpode_mem, Tout); flag = CPDense(cpode_mem, 4); /* USER-PROVIDED PROJECTION FUNCTION */ /* flag = CPodeProjDefine(cpode_mem, proj, NULL); */ /* INTERNAL PROJECTION FUNCTION */ ctols = N_VNew_Serial(2); Ith(ctols,1) = 1.0e-8; Ith(ctols,2) = 1.0e-8; flag = CPodeProjInit(cpode_mem, CP_PROJ_L2NORM, CP_CNSTR_NONLIN, cfun, NULL, ctols); flag = CPodeSetProjTestCnstr(cpode_mem, TRUE); flag = CPDenseProj(cpode_mem, 2, 4, CPDIRECT_LU); flag = CPodeSetProjUpdateErrEst(cpode_mem, FALSE); /* DISABLE PROJECTION */ /* CPodeSetProjFrequency(cpode_mem, 0); */ /* INTEGRATE TO FINAL TIME */ /* flag = CPode(cpode_mem, Tout, &t, yy, yp, CP_NORMAL_TSTOP); x = Ith(yy,1); y = Ith(yy,2); xd = Ith(yy,3); yd = Ith(yy,4); g = x*x + y*y - 1.0; Ith(yy,1) = x - 1.0; Ith(yy,2) = y - 0.0; Ith(yy,3) = xd - 0.0; Ith(yy,4) = yd - 0.0; printf("%14.10e %14.10e %14.10e %14.10e | %14.10e\n", Ith(yy,1),Ith(yy,2),Ith(yy,3),Ith(yy,4),g); */ /* INTEGRATE THROUGH A SEQUENCE OF TIMES */ t = 0.0; for(iout=1; iout<=Nout; iout++) { tout = iout*1.0; flag = CPode(cpode_mem, tout, &t, yy, yp, CP_NORMAL_TSTOP); if (flag < 0) break; x = Ith(yy,1); y = Ith(yy,2); xd = Ith(yy,3); yd = Ith(yy,4); g = x*x + y*y - 1.0; printf(" -------------- %lf %14.10lf %14.10lf %14.10lf %14.10lf %14.10lf\n", t, x,y,xd,yd,g); } PrintFinalStats(cpode_mem); N_VDestroy_Serial(yy); N_VDestroy_Serial(yp); N_VDestroy_Serial(ctols); CPodeFree(&cpode_mem); return(0); }
int main() { PbData data; realtype R, L, m, g, V0; void *cpode_mem; N_Vector yy, yp, ctols; realtype reltol, abstol; realtype t0, tf, t; realtype x1, y1, x2, y2; realtype vx1, vy1, vx2, vy2; int flag, Neq, Nc; int rdir[1], iroots[1]; FILE *fout; /* -------------------------------- * INITIALIZATIONS * -------------------------------- */ R = 0.1; /* ball radius */ L = 1.0; /* pendulum length */ m = 1.0; /* pendulum mass */ g = 9.8; /* gravitational acc. */ V0 = 3.0; /* initial velocity for pendulum 1 */ /* Set-up user data structure */ data = (PbData)malloc(sizeof *data); data->R = R; data->L = L; data->m = m; data->g = g; /* Problem dimensions */ Neq = 2*2*2; Nc = 2*2; /* Solution vectors */ yy = N_VNew_Serial(Neq); yp = N_VNew_Serial(Neq); /* Integration limits */ t0 = 0.0; tf = 6.0; /* Integration and projection tolerances */ reltol = 1.0e-8; abstol = 1.0e-8; ctols = N_VNew_Serial(Nc); N_VConst(1.0e-8, ctols); /* Direction of monitored events * (only zero-crossing with decreasing even function) */ rdir[0] = -1; /* -------------------------------- * CASE 1 * -------------------------------- */ fout = fopen("newton1.out","w"); /* Initial conditions */ NV_Ith_S(yy,0) = R; NV_Ith_S(yy,4) = -R; NV_Ith_S(yy,1) = -L; NV_Ith_S(yy,5) = -L; NV_Ith_S(yy,2) = V0; NV_Ith_S(yy,6) = 0.0; NV_Ith_S(yy,3) = 0.0; NV_Ith_S(yy,7) = 0.0; /* Initialize solver */ cpode_mem = CPodeCreate(CP_EXPL, CP_BDF, CP_NEWTON); flag = CPodeInit(cpode_mem, ffun1, data, t0, yy, yp, CP_SS, reltol, &abstol); flag = CPDense(cpode_mem, Neq); flag = CPodeRootInit(cpode_mem, 1, gfun, data); flag = CPodeSetRootDirection(cpode_mem, rdir); /* Set-up the internal projection */ flag = CPodeProjInit(cpode_mem, CP_PROJ_L2NORM, CP_CNSTR_NONLIN, cfun, data, ctols); flag = CPodeSetProjTestCnstr(cpode_mem, TRUE); flag = CPDenseProj(cpode_mem, Nc, Neq, CPDIRECT_LU); /* Integrate in ONE_STEP mode, while monitoring events */ t = t0; while(t<tf) { flag = CPode(cpode_mem, tf, &t, yy, yp, CP_ONE_STEP); if (flag < 0) break; x1 = NV_Ith_S(yy,0); x2 = NV_Ith_S(yy,4); y1 = NV_Ith_S(yy,1); y2 = NV_Ith_S(yy,5); vx1 = NV_Ith_S(yy,2); vx2 = NV_Ith_S(yy,6); vy1 = NV_Ith_S(yy,3); vy2 = NV_Ith_S(yy,7); fprintf(fout, "%lf %14.10lf %14.10lf %14.10lf %14.10lf %14.10lf %14.10lf %14.10lf %14.10lf", t, x1, y1, x2, y2, vx1, vy1, vx2, vy2); if (flag == CP_ROOT_RETURN) { CPodeGetRootInfo(cpode_mem, iroots); fprintf(fout, " %d\n", iroots[0]); /* Note: the test iroots[0]<0 is really needed ONLY if not using rdir */ if (iroots[0] < 0) { /* Update velocities in yy */ contact(yy, data); /* reinitialize CPODES solver */ flag = CPodeReInit(cpode_mem, ffun1, data, t, yy, yp, CP_SS, reltol, &abstol); } } else { fprintf(fout, " 0\n"); } } PrintFinalStats(cpode_mem); CPodeFree(&cpode_mem); fclose(fout); /* -------------------------------- * CASE 2 * -------------------------------- */ fout = fopen("newton2.out","w"); /* Initial conditions */ NV_Ith_S(yy,0) = R; NV_Ith_S(yy,4) = -R; NV_Ith_S(yy,1) = -L; NV_Ith_S(yy,5) = -L; NV_Ith_S(yy,2) = 0.0; NV_Ith_S(yy,6) = 0.0; NV_Ith_S(yy,3) = 0.0; NV_Ith_S(yy,7) = 0.0; /* Initialize solver */ cpode_mem = CPodeCreate(CP_EXPL, CP_BDF, CP_NEWTON); flag = CPodeInit(cpode_mem, ffun2, data, t0, yy, yp, CP_SS, reltol, &abstol); flag = CPDense(cpode_mem, Neq); flag = CPodeRootInit(cpode_mem, 1, gfun, data); flag = CPodeSetRootDirection(cpode_mem, rdir); /* Set-up the internal projection */ flag = CPodeProjInit(cpode_mem, CP_PROJ_L2NORM, CP_CNSTR_NONLIN, cfun, data, ctols); flag = CPodeSetProjTestCnstr(cpode_mem, TRUE); flag = CPDenseProj(cpode_mem, Nc, Neq, CPDIRECT_LU); /* Integrate in ONE_STEP mode, while monitoring events */ t = t0; while(t<tf) { flag = CPode(cpode_mem, tf, &t, yy, yp, CP_ONE_STEP); if (flag < 0) break; x1 = NV_Ith_S(yy,0); x2 = NV_Ith_S(yy,4); y1 = NV_Ith_S(yy,1); y2 = NV_Ith_S(yy,5); vx1 = NV_Ith_S(yy,2); vx2 = NV_Ith_S(yy,6); vy1 = NV_Ith_S(yy,3); vy2 = NV_Ith_S(yy,7); fprintf(fout, "%lf %14.10lf %14.10lf %14.10lf %14.10lf %14.10lf %14.10lf %14.10lf %14.10lf", t, x1, y1, x2, y2, vx1, vy1, vx2, vy2); if (flag == CP_ROOT_RETURN) { CPodeGetRootInfo(cpode_mem, iroots); fprintf(fout, " %d\n", iroots[0]); /* Note: the test iroots[0]<0 is really needed ONLY if not using rdir */ if (iroots[0] < 0) { /* Update velocities in yy */ contact(yy, data); /* reinitialize CPODES solver */ flag = CPodeReInit(cpode_mem, ffun2, data, t, yy, yp, CP_SS, reltol, &abstol); } } else { fprintf(fout, " 0\n"); } } PrintFinalStats(cpode_mem); CPodeFree(&cpode_mem); fclose(fout); /* -------------------------------- * CLEAN-UP * -------------------------------- */ free(data); N_VDestroy_Serial(yy); N_VDestroy_Serial(yp); N_VDestroy_Serial(ctols); return(0); }