Ejemplo n.º 1
0
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);
}
Ejemplo n.º 2
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);
}