Esempio n. 1
0
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);
}
Esempio 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);
}