int main() { void *fct, *jac; void *cpode_mem; N_Vector yy, yp, abstol; realtype reltol, t, tout; int flag, flagr, iout; int rootsfound[2]; /* Create serial vectors of length NEQ for I.C. and abstol */ yy = N_VNew_Serial(NEQ); yp = N_VNew_Serial(NEQ); abstol = N_VNew_Serial(NEQ); /* Initialize y */ Ith(yy,1) = Y1; Ith(yy,2) = Y2; Ith(yy,3) = Y3; /* Set tolerances */ reltol = RTOL; Ith(abstol,1) = ATOL1; Ith(abstol,2) = ATOL2; Ith(abstol,3) = ATOL3; if (ODE == CP_EXPL) { fct = (void *)f; jac = (void *)jacE; } else { f(T0, yy, yp, NULL); fct = (void *)res; jac = (void *)jacI; } /* Initialize solver */ cpode_mem = CPodeCreate(ODE, CP_BDF, CP_NEWTON); flag = CPodeInit(cpode_mem, fct, NULL, T0, yy, yp, CP_SV, reltol, abstol); /* Set initial step size */ /* { realtype h0; h0 = 8.5e-14; flag = CPodeSetInitStep(cpode_mem, h0); } */ /* Call CPodeRootInit to specify the root function g with 2 components */ flag = CPodeRootInit(cpode_mem, 2, g, NULL); /* Call CPDense to specify the CPDENSE dense linear solver */ flag = CPDense(cpode_mem, NEQ); /* Set the Jacobian routine (comment out for internal DQ) */ flag = CPDlsSetJacFn(cpode_mem, jac, NULL); /* In loop, call CPode, print results, and test for error. Break out of loop when NOUT preset output times have been reached. */ iout = 0; tout = T1; while(1) { flag = CPode(cpode_mem, tout, &t, yy, yp, CP_NORMAL); printf("At t = %0.4le y =%14.6le %14.6le %14.6le\n", t, Ith(yy,1), Ith(yy,2), Ith(yy,3)); if (flag < 0) break; if (flag == CP_ROOT_RETURN) { flagr = CPodeGetRootInfo(cpode_mem, rootsfound); printf(" rootsfound[] = %3d %3d\n", rootsfound[0],rootsfound[1]); } if (flag == CP_SUCCESS) { iout++; tout *= TMULT; } if (iout == NOUT) break; } /* Print some final statistics */ PrintFinalStats(cpode_mem); /* Free memory */ N_VDestroy_Serial(yy); N_VDestroy_Serial(yp); N_VDestroy_Serial(abstol); 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); }