Exemple #1
0
void FCV_REINIT(realtype *t0, realtype *y0, 
                int *iatol, realtype *rtol, realtype *atol, 
                int *ier)
{
  N_Vector Vatol;

  *ier = 0;

  /* Initialize all pointers to NULL */
  Vatol = NULL;

  /* Set data in F2C_CVODE_vec to y0 */
  N_VSetArrayPointer(y0, F2C_CVODE_vec);

  /* Call CVReInit */
  *ier = CVodeReInit(CV_cvodemem, *t0, F2C_CVODE_vec);

  /* Reset data pointers */
  N_VSetArrayPointer(NULL, F2C_CVODE_vec);

  /* On failure, exit */
  if (*ier != CV_SUCCESS) {
    *ier = -1;
    return;
  }

  /* Set tolerances */
  switch (*iatol) {
  case 1:
    *ier = CVodeSStolerances(CV_cvodemem, *rtol, *atol); 
    break;
  case 2:
    Vatol = NULL;
    Vatol = N_VCloneEmpty(F2C_CVODE_vec);
    if (Vatol == NULL) {
      *ier = -1;
      return;
    }
    N_VSetArrayPointer(atol, Vatol);
    *ier = CVodeSVtolerances(CV_cvodemem, *rtol, Vatol);
    N_VDestroy(Vatol);
    break;
  }

  /* On failure, exit */
  if (*ier != CV_SUCCESS) {
    *ier = -1;
    return;
  }

  return;
}
void ode_solver_setErrTol(ode_solver* solver, const double rel_tol,  double* abs_tol, const int abs_tol_len){
  
  if( (abs_tol_len != 1) && (abs_tol_len != solver->odeModel->N)){
    fprintf(stderr,"ode_solver_setErrTol: length of abs_tol must be 1 or equal to the number of variables in the ode model.\n");
    return ;
  }
  
  /* set tollerances to the cvode_mem internal structure */
  if ( abs_tol_len == 1 )
    CVodeSStolerances(solver->cvode_mem, rel_tol, abs_tol[0]);
  else{
    N_Vector abs_tol_vec =  N_VNewEmpty_Serial(abs_tol_len);		/* alloc */
    NV_DATA_S(abs_tol_vec) = abs_tol;
    CVodeSVtolerances(solver->cvode_mem, rel_tol, abs_tol_vec);
    N_VDestroy_Serial(abs_tol_vec);									/* free */
  }
}
Exemple #3
0
int main(int narg, char **args)
{
    realtype reltol, t, tout;
    N_Vector state, abstol;
    void *cvode_mem;
    int flag, flagr;
    int rootsfound[NRF];
    int rootdir[] = {1,};

    FILE *pout;
    if(!(pout = fopen("results/iaf_v.dat", "w"))){
        fprintf(stderr, "Cannot open file results/iaf_v.dat. Are you trying to write to a non-existent directory? Exiting...\n");
        exit(1);
    }

    state = abstol = NULL;
    cvode_mem = NULL;

    state = N_VNew_Serial(NEQ);
    if (check_flag((void *)state, "N_VNew_Serial", 0)) return(1);
    abstol = N_VNew_Serial(NEQ); 
    if (check_flag((void *)abstol, "N_VNew_Serial", 0)) return(1);
    
    realtype reset = -0.07;
    realtype C = 3.2e-12;
    realtype thresh = -0.055;
    realtype gleak = 2e-10;
    realtype eleak = -0.053;
    realtype p[] = {reset, C, thresh, gleak, eleak, };

    realtype v = reset;
    NV_Ith_S(state, 0) = reset;

    reltol = RTOL;
    NV_Ith_S(abstol,0) = ATOL0;
 
    /* Allocations and initializations */
    cvode_mem = CVodeCreate(CV_BDF, CV_NEWTON);
    if (check_flag((void *)cvode_mem, "CVodeCreate", 0)) return(1);
    
    flag = CVodeInit(cvode_mem, dstate_dt, T0, state);
    if (check_flag(&flag, "CVodeInit", 1)) return(1);
   
    flag = CVodeSetUserData(cvode_mem, p);
    if (check_flag(&flag, "CVodeSetUserData", 1)) return(1);
   
    flag = CVodeSVtolerances(cvode_mem, reltol, abstol);
    if (check_flag(&flag, "CVodeSVtolerances", 1)) return(1);
   
        flag = CVodeRootInit(cvode_mem, NRF, root_functions);
    if (check_flag(&flag, "CVodeRootInit", 1)) return(1);

    CVodeSetRootDirection(cvode_mem, rootdir);
    if (check_flag(&flag, "CVodeSetRootDirection", 1)) return(1);
        
   
    flag = CVDense(cvode_mem, NEQ);
    if (check_flag(&flag, "CVDense", 1)) return(1);


    printf(" \n Integrating iaf \n\n");
    printf("#t v, \n");
    PrintOutput(pout, t, state);
   
    tout = DT;
    while(1) {
        flag = CVode(cvode_mem, tout, state, &t, CV_NORMAL);
        
        if(flag == CV_ROOT_RETURN) {
            /* Event detected */
            flagr = CVodeGetRootInfo(cvode_mem, rootsfound);
            if (check_flag(&flagr, "CVodeGetRootInfo", 1)) return(1);
            PrintRootInfo(t, state, rootsfound);
          
            if(rootsfound[0]){
                //condition_0
                v = NV_Ith_S(state, 0);
                NV_Ith_S(state, 0) = reset;

        }
            

        /* Restart integration with event-corrected state */
            flag = CVodeSetUserData(cvode_mem, p);
            if (check_flag(&flag, "CVodeSetUserData", 1)) return(1);
        CVodeReInit(cvode_mem, t, state);
        //PrintRootInfo(t, state, rootsfound);
    }
        else
                {
            PrintOutput(pout, t, state);
            if(check_flag(&flag, "CVode", 1)) break;
            if(flag == CV_SUCCESS) {
                tout += DT;
            }
            if (t >= T1) break;
        }

    }

    PrintFinalStats(cvode_mem);

    N_VDestroy_Serial(state);
    N_VDestroy_Serial(abstol);

    CVodeFree(&cvode_mem);

    fclose(pout);
    return(0);
}
int do_integrate(float t_start, float t_stop, int n_points)
{
  realtype reltol, t; 
  N_Vector y, abstol;
  void *cvode_mem;
  int flag, flagr, iout;


  y = abstol = NULL;
  cvode_mem = NULL;

  /* Create serial vector of length NEQ for I.C. and abstol */
  y = N_VNew_Serial(NEQ);
  if (check_flag((void *)y, "N_VNew_Serial", 0)) return(1);
  abstol = N_VNew_Serial(NEQ); 
  if (check_flag((void *)abstol, "N_VNew_Serial", 0)) return(1);

  
  //Setup the initial state values:
  setup_initial_states(y);
  setup_tolerances(abstol);

  /* Set the scalar relative tolerance */
  reltol = RTOL;


  /* Call CVodeCreate to create the solver memory and specify the 
   * Backward Differentiation Formula and the use of a Newton iteration */
  cvode_mem = CVodeCreate(CV_BDF, CV_NEWTON);
  if (check_flag((void *)cvode_mem, "CVodeCreate", 0)) return(1);
  
  /* Call CVodeInit to initialize the integrator memory and specify the
   * user's right hand side function in y'=f(t,y), the inital time T0, and
   * the initial dependent variable vector y. */
  flag = CVodeInit(cvode_mem, f, t_start, y);
  if (check_flag(&flag, "CVodeInit", 1)) return(1);

  /* Call CVodeSVtolerances to specify the scalar relative tolerance
   * and vector absolute tolerances */
  flag = CVodeSVtolerances(cvode_mem, reltol, abstol);
  if (check_flag(&flag, "CVodeSVtolerances", 1)) return(1);


  /* Call CVDense to specify the CVDENSE dense linear solver */
  flag = CVDense(cvode_mem, NEQ);
  if (check_flag(&flag, "CVDense", 1)) return(1);

  /* Set the Jacobian routine to Jac (user-supplied) */
  flag = CVDlsSetDenseJacFn(cvode_mem, Jac);
  if (check_flag(&flag, "CVDlsSetDenseJacFn", 1)) return(1);

  /* In loop, call CVode, print results, and test for error.*/
  printf(" \n3-species kinetics problem\n\n");

  iout = 0;  

  int i=0;
  for(i=1;i< n_points; i++)
  {
    float t_next = t_start + (t_stop-t_start)/n_points * i;
    printf("Advancing to: %f", t_next);

    flag = CVode(cvode_mem, t_next, y, &t, CV_NORMAL);
    loop_function(t,y);


    PrintOutput(t, Ith(y,1), Ith(y,2), Ith(y,3));

    //printf("MH: %d %f",iout,t_next);


    if (check_flag(&flag, "CVode", 1)) break;
    assert(flag==CV_SUCCESS);
  }


  /* Print some final statistics */
  PrintFinalStats(cvode_mem);

  /* Free y and abstol vectors */
  N_VDestroy_Serial(y);
  N_VDestroy_Serial(abstol);

  /* Free integrator memory */
  CVodeFree(&cvode_mem);

  return(0);
}
Exemple #5
0
int main()
{
  realtype reltol, t, tout;
  N_Vector y, abstol;
  void *cvode_mem;
  int flag, flagr, iout, nnz;
  int rootsfound[2];

  y = abstol = NULL;
  cvode_mem = NULL;

  /* Create serial vector of length NEQ for I.C. and abstol */
  y = N_VNew_Serial(NEQ);
  if (check_flag((void *)y, "N_VNew_Serial", 0)) return(1);
  abstol = N_VNew_Serial(NEQ); 
  if (check_flag((void *)abstol, "N_VNew_Serial", 0)) return(1);

  /* Initialize y */
  Ith(y,1) = Y1;
  Ith(y,2) = Y2;
  Ith(y,3) = Y3;

  /* Set the scalar relative tolerance */
  reltol = RTOL;
  /* Set the vector absolute tolerance */
  Ith(abstol,1) = ATOL1;
  Ith(abstol,2) = ATOL2;
  Ith(abstol,3) = ATOL3;

  /* Call CVodeCreate to create the solver memory and specify the 
   * Backward Differentiation Formula and the use of a Newton iteration */
  cvode_mem = CVodeCreate(CV_BDF, CV_NEWTON);
  if (check_flag((void *)cvode_mem, "CVodeCreate", 0)) return(1);
  
  /* Call CVodeInit to initialize the integrator memory and specify the
   * user's right hand side function in y'=f(t,y), the inital time T0, and
   * the initial dependent variable vector y. */
  flag = CVodeInit(cvode_mem, f, T0, y);
  if (check_flag(&flag, "CVodeInit", 1)) return(1);

  /* Call CVodeSVtolerances to specify the scalar relative tolerance
   * and vector absolute tolerances */
  flag = CVodeSVtolerances(cvode_mem, reltol, abstol);
  if (check_flag(&flag, "CVodeSVtolerances", 1)) return(1);

  /* Call CVodeRootInit to specify the root function g with 2 components */
  flag = CVodeRootInit(cvode_mem, 2, g);
  if (check_flag(&flag, "CVodeRootInit", 1)) return(1);

  /* Call CVSuperLUMT to specify the CVSuperLUMT sparse direct linear solver */
  nnz = NEQ * NEQ;
  flag = CVSuperLUMT(cvode_mem, 1, NEQ, nnz);
  if (check_flag(&flag, "CVSuperLUMT", 1)) return(1);

  /* Set the Jacobian routine to Jac (user-supplied) */
  flag = CVSlsSetSparseJacFn(cvode_mem, Jac);
  if (check_flag(&flag, "CVSlsSetSparseJacFn", 1)) return(1);

  /* In loop, call CVode, print results, and test for error.
     Break out of loop when NOUT preset output times have been reached.  */
  printf(" \n3-species kinetics problem\n\n");

  iout = 0;  tout = T1;
  while(1) {
    flag = CVode(cvode_mem, tout, y, &t, CV_NORMAL);
    PrintOutput(t, Ith(y,1), Ith(y,2), Ith(y,3));

    if (flag == CV_ROOT_RETURN) {
      flagr = CVodeGetRootInfo(cvode_mem, rootsfound);
      if (check_flag(&flagr, "CVodeGetRootInfo", 1)) return(1);
      PrintRootInfo(rootsfound[0],rootsfound[1]);
    }

    if (check_flag(&flag, "CVode", 1)) break;
    if (flag == CV_SUCCESS) {
      iout++;
      tout *= TMULT;
    }

    if (iout == NOUT) break;
  }

  /* Print some final statistics */
  PrintFinalStats(cvode_mem);

  /* Free y and abstol vectors */
  N_VDestroy_Serial(y);
  N_VDestroy_Serial(abstol);

  /* Free integrator memory */
  CVodeFree(&cvode_mem);

  return(0);
}
  void CVodesIntegrator::initialize(double t0, FuncEval& func) 
  {
    m_neq = func.neq();
    m_t0  = t0;

    if (m_y) {
      N_VDestroy_Serial(nv(m_y));    // free solution vector if already allocated
    }
    m_y = reinterpret_cast<void*>(N_VNew_Serial(m_neq));   // allocate solution vector
    for (int i=0; i<m_neq; i++) {
      NV_Ith_S(nv(m_y), i) = 0.0;
    }
    // check abs tolerance array size
    if (m_itol == CV_SV && m_nabs < m_neq) 
      throw CVodesErr("not enough absolute tolerance values specified.");

    func.getInitialConditions(m_t0, m_neq, NV_DATA_S(nv(m_y)));

    if (m_cvode_mem) CVodeFree(&m_cvode_mem);

    /*
     *  Specify the method and the iteration type:
     *      Cantera Defaults:
     *         CV_BDF  - Use BDF methods 
     *         CV_NEWTON - use newton's method 
     */
    m_cvode_mem = CVodeCreate(m_method, m_iter);
    if (!m_cvode_mem) throw CVodesErr("CVodeCreate failed.");

    int flag = 0;
#if defined(SUNDIALS_VERSION_22) || defined(SUNDIALS_VERSION_23)
    if (m_itol == CV_SV) {
      // vector atol
      flag = CVodeMalloc(m_cvode_mem, cvodes_rhs, m_t0, nv(m_y), m_itol,
			 m_reltol, nv(m_abstol));
    }
    else {
      // scalar atol
      flag = CVodeMalloc(m_cvode_mem, cvodes_rhs, m_t0, nv(m_y), m_itol,
			 m_reltol, &m_abstols);
    }
    if (flag != CV_SUCCESS) {
      if (flag == CV_MEM_FAIL) {
	throw CVodesErr("Memory allocation failed.");
      }
      else if (flag == CV_ILL_INPUT) {
	throw CVodesErr("Illegal value for CVodeMalloc input argument.");
      }
      else 
	throw CVodesErr("CVodeMalloc failed.");
    }
#elif defined(SUNDIALS_VERSION_24)

    flag = CVodeInit(m_cvode_mem, cvodes_rhs, m_t0, nv(m_y));
    if (flag != CV_SUCCESS) {
      if (flag == CV_MEM_FAIL) {
	throw CVodesErr("Memory allocation failed.");
      } else if (flag == CV_ILL_INPUT) {
	throw CVodesErr("Illegal value for CVodeInit input argument.");
      } else {
	throw CVodesErr("CVodeInit failed.");
      }
    }

    if (m_itol == CV_SV) {
      flag = CVodeSVtolerances(m_cvode_mem, m_reltol, nv(m_abstol));
    } else {
      flag = CVodeSStolerances(m_cvode_mem, m_reltol, m_abstols);
    }
    if (flag != CV_SUCCESS) {
      if (flag == CV_MEM_FAIL) {
	throw CVodesErr("Memory allocation failed.");
      } else if (flag == CV_ILL_INPUT) {
	throw CVodesErr("Illegal value for CVodeInit input argument.");
      } else {
	throw CVodesErr("CVodeInit failed.");
      }
    }
#else
    printf("unknown sundials verson\n");
    exit(-1);
#endif



    if (m_type == DENSE + NOJAC) {
      long int N = m_neq;
      CVDense(m_cvode_mem, N);
    }
    else if (m_type == DIAG) {
      CVDiag(m_cvode_mem);
    }
    else if (m_type == GMRES) {
      CVSpgmr(m_cvode_mem, PREC_NONE, 0);
    }
    else if (m_type == BAND + NOJAC) {
      long int N = m_neq;
      long int nu = m_mupper;
      long int nl = m_mlower;
      CVBand(m_cvode_mem, N, nu, nl);
    }
    else {
      throw CVodesErr("unsupported option");
    }

    // pass a pointer to func in m_data 
    m_fdata = new FuncData(&func, func.nparams());

    //m_data = (void*)&func;
#if defined(SUNDIALS_VERSION_22) || defined(SUNDIALS_VERSION_23)
    flag = CVodeSetFdata(m_cvode_mem, (void*)m_fdata);
    if (flag != CV_SUCCESS) {
      throw CVodesErr("CVodeSetFdata failed.");
    }
#elif defined(SUNDIALS_VERSION_24)
    flag = CVodeSetUserData(m_cvode_mem, (void*)m_fdata);
    if (flag != CV_SUCCESS) {
      throw CVodesErr("CVodeSetUserData failed.");
    }
#endif
    if (func.nparams() > 0) {
      sensInit(t0, func);
      flag = CVodeSetSensParams(m_cvode_mem, DATA_PTR(m_fdata->m_pars), 
				NULL, NULL);
    }

    // set options
    if (m_maxord > 0)
      flag = CVodeSetMaxOrd(m_cvode_mem, m_maxord);
    if (m_maxsteps > 0)
      flag = CVodeSetMaxNumSteps(m_cvode_mem, m_maxsteps);
    if (m_hmax > 0)
      flag = CVodeSetMaxStep(m_cvode_mem, m_hmax);
  }
Bloch_McConnell_CV_Model::Bloch_McConnell_CV_Model     () {

    m_world->solverSettings = new bmnvec;
   /* for (int i=0;i<OPT_SIZE;i++) {m_iopt[i]=0; m_ropt[i]=0.0;}
    m_iopt[MXSTEP] = 1000000;
    m_ropt[HMAX]   = 10000.0;// the maximum stepsize in msec of the integrator*/
    m_reltol       = RTOL;

    //cvode2.5:
    // create cvode memory pointer; no mallocs done yet.
 //   m_cvode_mem = CVodeCreate(CV_BDF,CV_NEWTON);
   m_cvode_mem = CVodeCreate(CV_ADAMS,CV_FUNCTIONAL);

    // cvode allocate memory.
    // do CVodeMalloc with dummy values y0,abstol once here;
    // -> CVodeReInit can later be used



    //HACK
    int pools = m_world->GetNoOfCompartments();

    N_Vector y0,abstol;
    y0		= N_VNew_Serial(NEQ*pools);
    abstol	= N_VNew_Serial(NEQ*pools);
    ((bmnvec*) (m_world->solverSettings))->abstol = N_VNew_Serial(pools*NEQ);

    for(int i = 0; i< pools*NEQ; i+=NEQ){
    	NV_Ith_S(y0,AMPL+i) = 0.0; NV_Ith_S(y0,PHASE+i) = 0.0; NV_Ith_S(y0,ZC+i) = 0.0;
    	NV_Ith_S(abstol,AMPL+i) = ATOL1; NV_Ith_S(abstol,PHASE+i) = ATOL2; NV_Ith_S(abstol,ZC+i) = ATOL3;
    }
	
#ifndef CVODE26
    if(CVodeMalloc(m_cvode_mem,bloch,0,y0,CV_SV,m_reltol,abstol) != CV_SUCCESS ) {
    	cout << "CVodeMalloc failed! aborting..." << endl;exit (-1);
    }
    if(CVodeSetFdata(m_cvode_mem, (void *) m_world) !=CV_SUCCESS) {
    	cout << "CVode function data could not be set. Panic!" << endl;exit (-1);
    }

#else
    if(CVodeInit(m_cvode_mem,bloch,0,y0) != CV_SUCCESS ) {
    	cout << "CVodeInit failed! aborting..." << endl;exit (-1);
    }
    if(CVodeSVtolerances(m_cvode_mem, m_reltol, abstol)!= CV_SUCCESS){
    	cout << "CVodeSVtolerances failed! aborting..." << endl;exit (-1);
    }
    if(CVodeSetUserData(m_cvode_mem, (void *) m_world) !=CV_SUCCESS) {
    	cout << "CVode function data could not be set. Panic!" << endl;exit (-1);
    }
#endif

	/*    int flag;
	int blub = (3*pools);
	flag = CVDense(m_cvode_mem, blub);
	if (flag == CVDENSE_SUCCESS)
		cout<< "great" <<endl;
	else
		cout<< "bad" <<endl;
	*/

    N_VDestroy_Serial(y0);
    N_VDestroy_Serial(abstol);

    /*if(CVodeSetFdata(m_cvode_mem, (void *) m_world) !=CV_SUCCESS) {
    	cout << "CVode function data could not be set. Panic!" << endl;
    	exit (-1);
    }
	
    // set CVODE initial step size
  //    CVodeSetInitStep(m_cvode_mem, 1e-4);
      // set CVODE maximum step size
      CVodeSetMaxErrTestFails(m_cvode_mem, 10);
      // set CVODE minimum step size
      CVodeSetMinStep(m_cvode_mem, 1e-15);
	*/
    CVodeSetMaxNumSteps(m_cvode_mem, 10000000);

   	// maximum number of warnings t+h = t (if number negative -> no warnings are issued )
   	CVodeSetMaxHnilWarns(m_cvode_mem,2);

}
Exemple #8
0
int main(int narg, char **args)
{
    realtype reltol, t, tout;
    N_Vector state, abstol;
    void *cvode_mem;
    int flag, flagr;
    int rootsfound[NRF];
    int rootdir[] = {1,1,1,};

    FILE *pout;
    pout = stdout;

    state = abstol = NULL;
    cvode_mem = NULL;

    state = N_VNew_Serial(NEQ);
    if (check_flag((void *)state, "N_VNew_Serial", 0)) return(1);
    abstol = N_VNew_Serial(NEQ); 
    if (check_flag((void *)abstol, "N_VNew_Serial", 0)) return(1);
    
    realtype a = 0.02;
    realtype b = 0.2;
    realtype c = -50;
    realtype d = 2;
    realtype I = 0;
    realtype v0 = -70;
    realtype p[] = {a, b, c, d, I, v0, };

    realtype v = v0;
    realtype u = b * v0;
    NV_Ith_S(state, 0) = v0;
    NV_Ith_S(state, 1) = b * v0;

    reltol = RTOL;
    NV_Ith_S(abstol,0) = ATOL0;
    NV_Ith_S(abstol,1) = ATOL1;
 
    /* Allocations and initializations */
    cvode_mem = CVodeCreate(CV_BDF, CV_NEWTON);
    if (check_flag((void *)cvode_mem, "CVodeCreate", 0)) return(1);
    
    flag = CVodeInit(cvode_mem, dstate_dt, T0, state);
    if (check_flag(&flag, "CVodeInit", 1)) return(1);
   
    flag = CVodeSetUserData(cvode_mem, p);
    if (check_flag(&flag, "CVodeSetUserData", 1)) return(1);
   
    flag = CVodeSVtolerances(cvode_mem, reltol, abstol);
    if (check_flag(&flag, "CVodeSVtolerances", 1)) return(1);
   
        flag = CVodeRootInit(cvode_mem, NRF, root_functions);
    if (check_flag(&flag, "CVodeRootInit", 1)) return(1);

    CVodeSetRootDirection(cvode_mem, rootdir);
    if (check_flag(&flag, "CVodeSetRootDirection", 1)) return(1);
        
   
    flag = CVDense(cvode_mem, NEQ);
    if (check_flag(&flag, "CVDense", 1)) return(1);


    printf(" \n Integrating izhikevich_burster \n\n");
    printf("#t v, u, \n");
    PrintOutput(pout, t, state);
   
    tout = DT;
    while(1) {
        flag = CVode(cvode_mem, tout, state, &t, CV_NORMAL);
        
        if(flag == CV_ROOT_RETURN) {
            /* Event detected */
            flagr = CVodeGetRootInfo(cvode_mem, rootsfound);
            if (check_flag(&flagr, "CVodeGetRootInfo", 1)) return(1);
            PrintRootInfo(t, state, rootsfound);
          
            if(rootsfound[0]){
                //spike
                v = NV_Ith_S(state, 0);
                u = NV_Ith_S(state, 1);
                NV_Ith_S(state, 0) = c;
                NV_Ith_S(state, 1) = u + d;

        }
            if(rootsfound[1]){
                //start_inj
                I = 5;
                p[0] = a;
                p[1] = b;
                p[2] = c;
                p[3] = d;
                p[4] = I;
                p[5] = v0;
        }
            if(rootsfound[2]){
                //end_inj
                I = 0;
                p[0] = a;
                p[1] = b;
                p[2] = c;
                p[3] = d;
                p[4] = I;
                p[5] = v0;
        }
            

        /* Restart integration with event-corrected state */
            flag = CVodeSetUserData(cvode_mem, p);
            if (check_flag(&flag, "CVodeSetUserData", 1)) return(1);
        CVodeReInit(cvode_mem, t, state);
        //PrintRootInfo(t, state, rootsfound);
    }
        else
                {
            PrintOutput(pout, t, state);
            if(check_flag(&flag, "CVode", 1)) break;
            if(flag == CV_SUCCESS) {
                tout += DT;
            }
            if (t >= T1) break;
        }

    }

    PrintFinalStats(cvode_mem);

    N_VDestroy_Serial(state);
    N_VDestroy_Serial(abstol);

    CVodeFree(&cvode_mem);

    fclose(pout);
    return(0);
}
void CVodesIntegrator::initialize(double t0, FuncEval& func)
{
    m_neq = func.neq();
    m_t0 = t0;
    m_time = t0;

    if (m_y) {
        N_VDestroy_Serial(m_y); // free solution vector if already allocated
    }
    m_y = N_VNew_Serial(static_cast<sd_size_t>(m_neq)); // allocate solution vector
    for (size_t i = 0; i < m_neq; i++) {
        NV_Ith_S(m_y, i) = 0.0;
    }
    // check abs tolerance array size
    if (m_itol == CV_SV && m_nabs < m_neq) {
        throw CVodesErr("not enough absolute tolerance values specified.");
    }

    func.getInitialConditions(m_t0, m_neq, NV_DATA_S(m_y));

    if (m_cvode_mem) {
        CVodeFree(&m_cvode_mem);
    }

    /*
     *  Specify the method and the iteration type:
     *      Cantera Defaults:
     *         CV_BDF  - Use BDF methods
     *         CV_NEWTON - use Newton's method
     */
    m_cvode_mem = CVodeCreate(m_method, m_iter);
    if (!m_cvode_mem) {
        throw CVodesErr("CVodeCreate failed.");
    }

    int flag = CVodeInit(m_cvode_mem, cvodes_rhs, m_t0, m_y);
    if (flag != CV_SUCCESS) {
        if (flag == CV_MEM_FAIL) {
            throw CVodesErr("Memory allocation failed.");
        } else if (flag == CV_ILL_INPUT) {
            throw CVodesErr("Illegal value for CVodeInit input argument.");
        } else {
            throw CVodesErr("CVodeInit failed.");
        }
    }
    CVodeSetErrHandlerFn(m_cvode_mem, &cvodes_err, this);

    if (m_itol == CV_SV) {
        flag = CVodeSVtolerances(m_cvode_mem, m_reltol, m_abstol);
    } else {
        flag = CVodeSStolerances(m_cvode_mem, m_reltol, m_abstols);
    }
    if (flag != CV_SUCCESS) {
        if (flag == CV_MEM_FAIL) {
            throw CVodesErr("Memory allocation failed.");
        } else if (flag == CV_ILL_INPUT) {
            throw CVodesErr("Illegal value for CVodeInit input argument.");
        } else {
            throw CVodesErr("CVodeInit failed.");
        }
    }

    // pass a pointer to func in m_data
    m_fdata.reset(new FuncData(&func, func.nparams()));

    flag = CVodeSetUserData(m_cvode_mem, m_fdata.get());
    if (flag != CV_SUCCESS) {
        throw CVodesErr("CVodeSetUserData failed.");
    }
    if (func.nparams() > 0) {
        sensInit(t0, func);
        flag = CVodeSetSensParams(m_cvode_mem, m_fdata->m_pars.data(),
                                  NULL, NULL);
    }
    applyOptions();
}
Exemple #10
0
void Cvode::initialize()
{
  _properties = dynamic_cast<ISystemProperties*>(_system);
  _continuous_system = dynamic_cast<IContinuous*>(_system);
  _event_system = dynamic_cast<IEvent*>(_system);
  _mixed_system = dynamic_cast<IMixedSystem*>(_system);
  _time_system = dynamic_cast<ITime*>(_system);
  IGlobalSettings* global_settings = dynamic_cast<ISolverSettings*>(_cvodesettings)->getGlobalSettings();
  // Kennzeichnung, dass initialize()() (vor der Integration) aufgerufen wurde
  _idid = 5000;
  _tLastEvent = 0.0;
  _event_n = 0;
  SolverDefaultImplementation::initialize();
  _dimSys = _continuous_system->getDimContinuousStates();
  _dimZeroFunc = _event_system->getDimZeroFunc();

  if (_dimSys == 0)
    _dimSys = 1; // introduce dummy state

  if (_dimSys <= 0)
  {
    _idid = -1;
    throw ModelicaSimulationError(SOLVER,"Cvode::initialize()");
  }
  else
  {
    // Allocate state vectors, stages and temporary arrays
    if (_z)
      delete[] _z;
    if (_zInit)
      delete[] _zInit;
    if (_zWrite)
      delete[] _zWrite;
    if (_zeroSign)
      delete[] _zeroSign;
    if (_absTol)
      delete[] _absTol;
  if(_delta)
    delete [] _delta;
    if(_deltaInv)
    delete [] _deltaInv;
    if(_ysave)
    delete [] _ysave;

    _z = new double[_dimSys];
    _zInit = new double[_dimSys];
    _zWrite = new double[_dimSys];
    _zeroSign = new int[_dimZeroFunc];
    _absTol = new double[_dimSys];
  _delta =new double[_dimSys];
    _deltaInv =new double[_dimSys];
  _ysave =new double[_dimSys];

    memset(_z, 0, _dimSys * sizeof(double));
    memset(_zInit, 0, _dimSys * sizeof(double));
  memset(_ysave, 0, _dimSys * sizeof(double));

    // Counter initialisieren
    _outStps = 0;

    if (_cvodesettings->getDenseOutput())
    {
      // Ausgabeschrittweite
      _hOut = global_settings->gethOutput();

    }

    // Allocate memory for the solver
    _cvodeMem = CVodeCreate(CV_BDF, CV_NEWTON);
    if (check_flag((void*) _cvodeMem, "CVodeCreate", 0))
    {
      _idid = -5;
      throw ModelicaSimulationError(SOLVER,/*_idid,_tCurrent,*/"Cvode::initialize()");
    }

    //
    // Make Cvode ready for integration
    //

    // Set initial values for CVODE
    _continuous_system->evaluateAll(IContinuous::CONTINUOUS);
    _continuous_system->getContinuousStates(_zInit);
    memcpy(_z, _zInit, _dimSys * sizeof(double));

    // Get nominal values
    _absTol[0] = 1.0; // in case of dummy state
    _continuous_system->getNominalStates(_absTol);
    for (int i = 0; i < _dimSys; i++)
      _absTol[i] *= dynamic_cast<ISolverSettings*>(_cvodesettings)->getATol();

    _CV_y0 = N_VMake_Serial(_dimSys, _zInit);
    _CV_y = N_VMake_Serial(_dimSys, _z);
    _CV_yWrite = N_VMake_Serial(_dimSys, _zWrite);
    _CV_absTol = N_VMake_Serial(_dimSys, _absTol);

    if (check_flag((void*) _CV_y0, "N_VMake_Serial", 0))
    {
      _idid = -5;
      throw ModelicaSimulationError(SOLVER,"Cvode::initialize()");
    }

    // Initialize Cvode (Initial values are required)
    _idid = CVodeInit(_cvodeMem, CV_fCallback, _tCurrent, _CV_y0);
    if (_idid < 0)
    {
      _idid = -5;
      throw ModelicaSimulationError(SOLVER,"Cvode::initialize()");
    }

    // Set Tolerances
    _idid = CVodeSVtolerances(_cvodeMem, dynamic_cast<ISolverSettings*>(_cvodesettings)->getRTol(), _CV_absTol);    // RTOL and ATOL
    if (_idid < 0)
      throw ModelicaSimulationError(SOLVER,"CVode::initialize()");

    // Set the pointer to user-defined data
    _idid = CVodeSetUserData(_cvodeMem, _data);
    if (_idid < 0)
      throw ModelicaSimulationError(SOLVER,"Cvode::initialize()");

    _idid = CVodeSetInitStep(_cvodeMem, 1e-6);    // INITIAL STEPSIZE
    if (_idid < 0)
      throw ModelicaSimulationError(SOLVER,"Cvode::initialize()");

    _idid = CVodeSetMaxOrd(_cvodeMem, 5);       // Max Order
    if (_idid < 0)
      throw ModelicaSimulationError(SOLVER,"CVoder::initialize()");

    _idid = CVodeSetMaxConvFails(_cvodeMem, 100);       // Maximale Fehler im Konvergenztest
    if (_idid < 0)
      throw ModelicaSimulationError(SOLVER,"CVoder::initialize()");

    _idid = CVodeSetStabLimDet(_cvodeMem, TRUE);       // Stability Detection
    if (_idid < 0)
      throw ModelicaSimulationError(SOLVER,"CVoder::initialize()");

    _idid = CVodeSetMinStep(_cvodeMem, dynamic_cast<ISolverSettings*>(_cvodesettings)->getLowerLimit());       // MINIMUM STEPSIZE
    if (_idid < 0)
      throw ModelicaSimulationError(SOLVER,"CVode::initialize()");

    _idid = CVodeSetMaxStep(_cvodeMem, global_settings->getEndTime() / 10.0);       // MAXIMUM STEPSIZE
    if (_idid < 0)
      throw ModelicaSimulationError(SOLVER,"CVode::initialize()");

    _idid = CVodeSetMaxNonlinIters(_cvodeMem, 5);      // Max number of iterations
    if (_idid < 0)
      throw ModelicaSimulationError(SOLVER,"CVode::initialize()");
    _idid = CVodeSetMaxErrTestFails(_cvodeMem, 100);
    if (_idid < 0)
      throw ModelicaSimulationError(SOLVER,"CVode::initialize()");

    _idid = CVodeSetMaxNumSteps(_cvodeMem, 1e3);            // Max Number of steps
    if (_idid < 0)
      throw ModelicaSimulationError(SOLVER,/*_idid,_tCurrent,*/"Cvode::initialize()");

    // Initialize linear solver
    #ifdef USE_SUNDIALS_LAPACK
      _idid = CVLapackDense(_cvodeMem, _dimSys);
    #else
      _idid = CVDense(_cvodeMem, _dimSys);
    #endif
    if (_idid < 0)
      throw ModelicaSimulationError(SOLVER,"Cvode::initialize()");

  // Use own jacobian matrix
  // Check if Colored Jacobians are worth to use
   #if SUNDIALS_MAJOR_VERSION >= 2 || (SUNDIALS_MAJOR_VERSION == 2 && SUNDIALS_MINOR_VERSION >= 4)
    _maxColors = _system->getAMaxColors();
    if(_maxColors < _dimSys && _continuous_system->getDimContinuousStates() > 0)
    {
   // _idid = CVDlsSetDenseJacFn(_cvodeMem, &CV_JCallback);
   // initializeColoredJac();
  }
  #endif

  if (_idid < 0)
      throw ModelicaSimulationError(SOLVER,"CVode::initialize()");

    if (_dimZeroFunc)
    {
      _idid = CVodeRootInit(_cvodeMem, _dimZeroFunc, &CV_ZerofCallback);

      memset(_zeroSign, 0, _dimZeroFunc * sizeof(int));
      _idid = CVodeSetRootDirection(_cvodeMem, _zeroSign);
      if (_idid < 0)
        throw ModelicaSimulationError(SOLVER,/*_idid,_tCurrent,*/"CVode::initialize()");
      memset(_zeroSign, -1, _dimZeroFunc * sizeof(int));
      memset(_zeroVal, -1, _dimZeroFunc * sizeof(int));

    }


    _cvode_initialized = true;

    LOGGER_WRITE("Cvode: initialized",LC_SOLV,LL_DEBUG);
  }
}
/** \brief Call the ODE solver.
 *
 * \param neq The number of equations.
 * \param x_f A pointer to a vector of \c neq variables, giving the
 * initial state vector on entry and the final state vector on exit.
 * \param abstol_f A pointer to a vector of \c neq variables, giving
 * the absolute error tolerance for the corresponding state vector
 * component.
 * \param reltol_f The scalar relative tolerance.
 * \param t_initial_f The initial time (s).
 * \param t_final_f The final time (s).
 * \return A result code (0 is success).
 */
int condense_solver(int neq, double *x_f, double *abstol_f, double reltol_f,
		    double t_initial_f, double t_final_f)
{
	realtype reltol, t_initial, t_final, t, tout;
	N_Vector y, abstol;
	void *cvode_mem;
	CVodeMem cv_mem;
	int flag, i, pretype, maxl;
	realtype *y_data, *abstol_data;

	y = abstol = NULL;
	cvode_mem = NULL;

	y = N_VNew_Serial(neq);
	if (condense_check_flag((void *)y, "N_VNew_Serial", 0))
                return PMC_CONDENSE_SOLVER_INIT_Y;

	abstol = N_VNew_Serial(neq);
	if (condense_check_flag((void *)abstol, "N_VNew_Serial", 0))
                return PMC_CONDENSE_SOLVER_INIT_ABSTOL;

	y_data = NV_DATA_S(y);
	abstol_data = NV_DATA_S(abstol);
	for (i = 0; i < neq; i++) {
		y_data[i] = x_f[i];
		abstol_data[i] = abstol_f[i];
	}

	reltol = reltol_f;
	t_initial = t_initial_f;
	t_final = t_final_f;

	cvode_mem = CVodeCreate(CV_BDF, CV_NEWTON);
	if (condense_check_flag((void *)cvode_mem, "CVodeCreate", 0))
                return PMC_CONDENSE_SOLVER_INIT_CVODE_MEM;

	flag = CVodeInit(cvode_mem, condense_vf, t_initial, y);
	if (condense_check_flag(&flag, "CVodeInit", 1))
                return PMC_CONDENSE_SOLVER_INIT_CVODE;

	flag = CVodeSVtolerances(cvode_mem, reltol, abstol);
	if (condense_check_flag(&flag, "CVodeSVtolerances", 1))
                return PMC_CONDENSE_SOLVER_SVTOL;

	flag = CVodeSetMaxNumSteps(cvode_mem, 100000);
	if (condense_check_flag(&flag, "CVodeSetMaxNumSteps", 1))
                return PMC_CONDENSE_SOLVER_SET_MAX_STEPS;

        /*******************************************************/
	// dense solver
	//flag = CVDense(cvode_mem, neq);
	//if (condense_check_flag(&flag, "CVDense", 1)) return(1);
        /*******************************************************/

        /*******************************************************/
	// iterative solver
	//pretype = PREC_LEFT;
	//maxl = 0;
	//flag = CVSptfqmr(cvode_mem, pretype, maxl);
	//if (condense_check_flag(&flag, "CVSptfqmr", 1)) return(1);

	//flag = CVSpilsSetJacTimesVecFn(cvode_mem, condense_jtimes);
	//if (condense_check_flag(&flag, "CVSpilsSetJacTimesVecFn", 1)) return(1);

	//flag = CVSpilsSetPreconditioner(cvode_mem, NULL, condense_prec);
	//if (condense_check_flag(&flag, "CVSpilsSetPreconditioner", 1)) return(1);
        /*******************************************************/

        /*******************************************************/
	// explicit solver
	cv_mem = (CVodeMem)cvode_mem;
	cv_mem->cv_linit = condense_solver_Init;
	cv_mem->cv_lsetup = condense_solver_Setup;
	cv_mem->cv_lsolve = condense_solver_Solve;
	cv_mem->cv_lfree = condense_solver_Free;
        /*******************************************************/

	t = t_initial;
	flag = CVode(cvode_mem, t_final, y, &t, CV_NORMAL);
	if (condense_check_flag(&flag, "CVode", 1))
                return PMC_CONDENSE_SOLVER_FAIL;

	for (i = 0; i < neq; i++) {
		x_f[i] = y_data[i];
	}

	N_VDestroy_Serial(y);
	N_VDestroy_Serial(abstol);
	CVodeFree(&cvode_mem);
	return PMC_CONDENSE_SOLVER_SUCCESS;
}
Exemple #12
0
void SundialsCvode::initialize()
{
    int flag = 0;
    if (_initialized) {
        // Starting over with a new IC, but the same ODE
        flag = CVodeReInit(sundialsMem, t0, y.forSundials());
        if (check_flag(&flag, "CVodeReInit", 1)) {
            throw DebugException("SundialsCvode::reInitialize: error in CVodeReInit");
        }

        CVodeSetMaxNumSteps(sundialsMem, maxNumSteps);
        CVodeSetMinStep(sundialsMem, minStep);
        return;
    }

    // On the first call to initialize, need to allocate and set up
    // the Sundials solver, set tolerances and link the ODE functions
    sundialsMem = CVodeCreate(linearMultistepMethod, nonlinearSolverMethod);
    if (check_flag((void *)sundialsMem, "CVodeCreate", 0)) {
        throw DebugException("SundialsCvode::initialize: error in CVodeCreate");
    }

    flag = CVodeInit(sundialsMem, f, t0, y.forSundials());
    if (check_flag(&flag, "CVodeMalloc", 1)) {
        throw DebugException("SundialsCvode::initialize: error in CVodeMalloc");
    }

    CVodeSVtolerances(sundialsMem, reltol, abstol.forSundials());
    CVodeSetUserData(sundialsMem, theODE);
    CVodeSetMaxNumSteps(sundialsMem, maxNumSteps);
    CVodeSetMinStep(sundialsMem, minStep);

    if (findRoots) {
        rootsFound.resize(nRoots);
        // Call CVodeRootInit to specify the root function g with nRoots components
        flag = CVodeRootInit(sundialsMem, nRoots, g);
        if (check_flag(&flag, "CVodeRootInit", 1)) {
            throw DebugException("SundialsCvode::initialize: error in CVodeRootInit");
        }
    }

    if (bandwidth_upper == -1 && bandwidth_lower == -1) {
        // Call CVDense to specify the CVDENSE dense linear solver
        flag = CVDense(sundialsMem, nEq);
        if (check_flag(&flag, "CVDense", 1)) {
            throw DebugException("SundialsCvode::initialize: error in CVDense");
        }

        // Set the Jacobian routine to denseJac (user-supplied)
        flag = CVDlsSetDenseJacFn(sundialsMem, denseJac);
        if (check_flag(&flag, "CVDlsSetDenseJacFn", 1)) {
            throw DebugException("SundialsCvode::initialize: error in CVDlsSetDenseJacFn");
        }
    } else {
        // Call CVDense to specify the CVBAND Banded linear solver
        flag = CVBand(sundialsMem, nEq, bandwidth_upper, bandwidth_lower);
        if (check_flag(&flag, "CVBand", 1)) {
            throw DebugException("SundialsCvode::initialize: error in CVBand");
        }

        // Set the Jacobian routine to bandJac (user-supplied)
        flag = CVDlsSetBandJacFn(sundialsMem, bandJac);
        if (check_flag(&flag, "CVDlsSetBandJacFn", 1)) {
            throw DebugException("SundialsCvode::initialize: error in CVDlsSetBandJacFn");
        }
    }

    _initialized = true;
}
Exemple #13
0
int main(int narg, char **args)
{
    realtype reltol, t, tout;
    N_Vector state, abstol;
    void *cvode_mem;
    int flag, flagr;

    FILE *pout;
    if(!(pout = fopen("Locke2008_Circadian_Clock.dat", "w"))){
        fprintf(stderr, "Cannot open file Locke2008_Circadian_Clock.dat. Are you trying to write to a non-existent directory? Exiting...\n");
        exit(1);
    }

    state = abstol = NULL;
    cvode_mem = NULL;

    state = N_VNew_Serial(NEQ);
    if (check_flag((void *)state, "N_VNew_Serial", 0)) return(1);
    abstol = N_VNew_Serial(NEQ); 
    if (check_flag((void *)abstol, "N_VNew_Serial", 0)) return(1);
    
    realtype Kc = 4.8283;
    realtype v_4 = 1.0841;
    realtype v_6 = 4.6645;
    realtype vc = 6.7924;
    realtype v_1 = 6.8355;
    realtype v_2 = 8.4297;
    realtype K = 1.0;
    realtype v_8 = 3.5216;
    realtype L = 0.0;
    realtype n = 5.6645;
    realtype k3 = 0.1177;
    realtype K2 = 0.291;
    realtype K1 = 2.7266;
    realtype k7 = 0.2282;
    realtype K6 = 9.9849;
    realtype k5 = 0.3352;
    realtype K4 = 8.1343;
    realtype K8 = 7.4519;
    realtype init_X1 = 4.25;
    realtype tscale = 1.0;
    realtype init_Z1 = 2.25;
    realtype init_Z2 = 0.0;
    realtype init_V1 = 2.5;
    realtype init_V2 = 0.0;
    realtype init_X2 = 0.0;
    realtype compartment = 1.0;
    realtype init_Y1 = 3.25;
    realtype init_Y2 = 0.0;
    realtype p[] = {Kc, v_4, v_6, vc, v_1, v_2, K, v_8, L, n, k3, K2, K1, k7, K6, k5, K4, K8, init_X1, tscale, init_Z1, init_Z2, init_V1, init_V2, init_X2, compartment, init_Y1, init_Y2, };

    realtype X1 = init_X1;
    realtype X2 = init_X2;
    realtype V1 = init_V1;
    realtype V2 = init_V2;
    realtype Y1 = init_Y1;
    realtype Y2 = init_Y2;
    realtype Z1 = init_Z1;
    realtype Z2 = init_Z2;
    NV_Ith_S(state, 0) = init_Y2;
    NV_Ith_S(state, 1) = init_V1;
    NV_Ith_S(state, 2) = init_Y1;
    NV_Ith_S(state, 3) = init_V2;
    NV_Ith_S(state, 4) = init_X2;
    NV_Ith_S(state, 5) = init_X1;
    NV_Ith_S(state, 6) = init_Z1;
    NV_Ith_S(state, 7) = init_Z2;

    reltol = RTOL;
    NV_Ith_S(abstol,0) = ATOL0;
    NV_Ith_S(abstol,1) = ATOL1;
    NV_Ith_S(abstol,2) = ATOL2;
    NV_Ith_S(abstol,3) = ATOL3;
    NV_Ith_S(abstol,4) = ATOL4;
    NV_Ith_S(abstol,5) = ATOL5;
    NV_Ith_S(abstol,6) = ATOL6;
    NV_Ith_S(abstol,7) = ATOL7;
 
    /* Allocations and initializations */
    cvode_mem = CVodeCreate(CV_BDF, CV_NEWTON);
    if (check_flag((void *)cvode_mem, "CVodeCreate", 0)) return(1);
    
    flag = CVodeInit(cvode_mem, dstate_dt, T0, state);
    if (check_flag(&flag, "CVodeInit", 1)) return(1);
   
    flag = CVodeSetUserData(cvode_mem, p);
    if (check_flag(&flag, "CVodeSetUserData", 1)) return(1);
   
    flag = CVodeSVtolerances(cvode_mem, reltol, abstol);
    if (check_flag(&flag, "CVodeSVtolerances", 1)) return(1);
   
        
   
    flag = CVDense(cvode_mem, NEQ);
    if (check_flag(&flag, "CVDense", 1)) return(1);


    printf(" \n Integrating Locke2008_Circadian_Clock_0 \n\n");
    printf("#t Y2, V1, Y1, V2, X2, X1, Z1, Z2, \n");
    PrintOutput(pout, t, state);
   
    tout = DT;
    while(1) {
        flag = CVode(cvode_mem, tout, state, &t, CV_NORMAL);
        
        {
            PrintOutput(pout, t, state);
            if(check_flag(&flag, "CVode", 1)) break;
            if(flag == CV_SUCCESS) {
                tout += DT;
            }
            if (t >= T1) break;
        }

    }

    PrintFinalStats(cvode_mem);

    N_VDestroy_Serial(state);
    N_VDestroy_Serial(abstol);

    CVodeFree(&cvode_mem);

    fclose(pout);
    return(0);
}
Exemple #14
0
void FCV_MALLOC(realtype *t0, realtype *y0,
                int *meth, int *iatol,
                realtype *rtol, realtype *atol,
                long int *iout, realtype *rout,
                long int *ipar, realtype *rpar,
                int *ier)
{
  int lmm;
  N_Vector Vatol;
  FCVUserData CV_userdata;

  *ier = 0;

  /* Check for required vector operations */
  if(F2C_CVODE_vec->ops->nvgetarraypointer == NULL ||
     F2C_CVODE_vec->ops->nvsetarraypointer == NULL) {
    *ier = -1;
    fprintf(stderr, "A required vector operation is not implemented.\n\n");
    return;
  }

  /* Initialize all pointers to NULL */
  CV_cvodemem = NULL;
  Vatol = NULL;
  FCVNullNonlinSol();

  /* initialize global constants to disable each option */
  CV_nrtfn = 0;
  CV_ls = -1;
  
  /* Create CVODE object */
  lmm = (*meth == 1) ? CV_ADAMS : CV_BDF;
  CV_cvodemem = CVodeCreate(lmm);
  if (CV_cvodemem == NULL) {
    *ier = -1;
    return;
  }
  
  /* Set and attach user data */
  CV_userdata = NULL;
  CV_userdata = (FCVUserData) malloc(sizeof *CV_userdata);
  if (CV_userdata == NULL) {
    *ier = -1;
    return;
  }
  CV_userdata->rpar = rpar;
  CV_userdata->ipar = ipar;

  *ier = CVodeSetUserData(CV_cvodemem, CV_userdata);
  if(*ier != CV_SUCCESS) {
    free(CV_userdata); CV_userdata = NULL;
    *ier = -1;
    return;
  }

  /* Set data in F2C_CVODE_vec to y0 */
  N_VSetArrayPointer(y0, F2C_CVODE_vec);

  /* Call CVodeInit */
  *ier = CVodeInit(CV_cvodemem, FCVf, *t0, F2C_CVODE_vec);

  /* Reset data pointers */
  N_VSetArrayPointer(NULL, F2C_CVODE_vec);

  /* On failure, exit */
  if(*ier != CV_SUCCESS) {
    free(CV_userdata); CV_userdata = NULL;
    *ier = -1;
    return;
  }

  /* Set tolerances */
  switch (*iatol) {
  case 1:
    *ier = CVodeSStolerances(CV_cvodemem, *rtol, *atol); 
    break;
  case 2:
    Vatol = NULL;
    Vatol = N_VCloneEmpty(F2C_CVODE_vec);
    if (Vatol == NULL) {
      free(CV_userdata); CV_userdata = NULL;
      *ier = -1;
      return;
    }
    N_VSetArrayPointer(atol, Vatol);
    *ier = CVodeSVtolerances(CV_cvodemem, *rtol, Vatol);
    N_VDestroy(Vatol);
    break;
  }

  /* On failure, exit */
  if(*ier != CV_SUCCESS) {
    free(CV_userdata); CV_userdata = NULL;
    *ier = -1;
    return;
  }

  /* Grab optional output arrays and store them in global variables */
  CV_iout = iout;
  CV_rout = rout;

  /* Store the unit roundoff in rout for user access */
  CV_rout[5] = UNIT_ROUNDOFF;

  return;
}
Exemple #15
0
int run_rate_state_sim(std::vector<std::vector<realtype> > &results, RSParams &params) {
	realtype		long_term_reltol, event_reltol, t, tout, tbase=0;
	N_Vector		y, long_term_abstol, event_abstol;
	unsigned int	i, n;
	int				flag, err_code;
	void			*long_term_cvode, *event_cvode, *current_cvode;
	
	// Create serial vector of length NEQ for I.C. and abstol
	y = N_VNew_Serial(params.num_eqs()*params.num_blocks());
	if (check_flag((void *)y, "N_VNew_Serial", 0)) return(1);
	long_term_abstol = N_VNew_Serial(params.num_eqs()*params.num_blocks()); 
	if (check_flag((void *)long_term_abstol, "N_VNew_Serial", 0)) return(1);
	event_abstol = N_VNew_Serial(params.num_eqs()*params.num_blocks()); 
	if (check_flag((void *)event_abstol, "N_VNew_Serial", 0)) return(1);
	
	// Initialize y
	for (i=0;i<params.num_blocks();++i) {
		NV_Ith_S(y,i*params.num_eqs()+EQ_X) = params.init_val(i, EQ_X);
		NV_Ith_S(y,i*params.num_eqs()+EQ_V) = params.init_val(i, EQ_V);
		NV_Ith_S(y,i*params.num_eqs()+EQ_H) = params.init_val(i, EQ_H);
	}
	
	/* Initialize interactions */
	/*interaction = new realtype[NBLOCKS*NBLOCKS];
	double int_level = 1e-2;
	double dropoff = 1.1;
	for (i=0;i<NBLOCKS;++i) {
		for (n=0;n<NBLOCKS;++n) {
			interaction[i*NBLOCKS+n] = (i==n?(1.0-int_level):int_level);
		}
	}*/
	
	/* Set the scalar relative tolerance */
	long_term_reltol = RCONST(1.0e-12);
	event_reltol = RCONST(1.0e-12);
	/* Set the vector absolute tolerance */
	for (i=0;i<params.num_blocks();++i) {
		Xth(long_term_abstol,i) = RCONST(1.0e-12);
		Vth(long_term_abstol,i) = RCONST(1.0e-12);
		Hth(long_term_abstol,i) = RCONST(1.0e-12);
		Xth(event_abstol,i) = RCONST(1.0e-12);
		Vth(event_abstol,i) = RCONST(1.0e-12);
		Hth(event_abstol,i) = RCONST(1.0e-12);
	}
	
	/* Call CVodeCreate to create the solver memory and specify the 
	 * Backward Differentiation Formula and the use of a Newton iteration */
	long_term_cvode = CVodeCreate(CV_BDF, CV_NEWTON);
	if (check_flag((void *)long_term_cvode, "CVodeCreate", 0)) return(1);
	event_cvode = CVodeCreate(CV_BDF, CV_NEWTON);
	if (check_flag((void *)event_cvode, "CVodeCreate", 0)) return(1);
	
	// Turn off error messages
	//CVodeSetErrFile(long_term_cvode, NULL);
	//CVodeSetErrFile(event_cvode, NULL);
	
	/* Call CVodeInit to initialize the integrator memory and specify the
	 * user's right hand side function in y'=f(t,y), the inital time T0, and
	 * the initial dependent variable vector y. */
	flag = CVodeInit(long_term_cvode, func, T0, y);
	if (check_flag(&flag, "CVodeInit", 1)) return(1);
	flag = CVodeInit(event_cvode, func, T0, y);
	if (check_flag(&flag, "CVodeInit", 1)) return(1);
	
	/* Call CVodeSVtolerances to specify the scalar relative tolerance
	 * and vector absolute tolerances */
	flag = CVodeSVtolerances(long_term_cvode, long_term_reltol, long_term_abstol);
	if (check_flag(&flag, "CVodeSVtolerances", 1)) return(1);
	flag = CVodeSVtolerances(event_cvode, event_reltol, event_abstol);
	if (check_flag(&flag, "CVodeSVtolerances", 1)) return(1);
	
	/* Set the root finding function */
	//flag = CVodeRootInit(long_term_cvode, params.num_blocks(), vel_switch_finder);
	//flag = CVodeRootInit(event_cvode, params.num_blocks(), vel_switch_finder);
	//if (check_flag(&flag, "CVodeRootInit", 1)) return(1);
	
	/* Call CVDense to specify the CVDENSE dense linear solver */
	//flag = CVSpbcg(cvode_mem, PREC_NONE, 0);
	//if (check_flag(&flag, "CVSpbcg", 1)) return(1);
	//flag = CVSpgmr(cvode_mem, PREC_NONE, 0);
	//if (check_flag(&flag, "CVSpgmr", 1)) return(1);
	flag = CVDense(long_term_cvode, params.num_eqs()*params.num_blocks());
	if (check_flag(&flag, "CVDense", 1)) return(1);
	flag = CVDense(event_cvode, params.num_eqs()*params.num_blocks());
	if (check_flag(&flag, "CVDense", 1)) return(1);
	
	flag = CVodeSetUserData(long_term_cvode, &params);
	if (check_flag(&flag, "CVodeSetUserData", 1)) return(1);
	flag = CVodeSetUserData(event_cvode, &params);
	if (check_flag(&flag, "CVodeSetUserData", 1)) return(1);
	
	CVodeSetMaxNumSteps(long_term_cvode, 100000);
	CVodeSetMaxNumSteps(event_cvode, 100000);
	
	/* Set the Jacobian routine to Jac (user-supplied) */
	flag = CVDlsSetDenseJacFn(long_term_cvode, Jac);
	if (check_flag(&flag, "CVDlsSetDenseJacFn", 1)) return(1);
	flag = CVDlsSetDenseJacFn(event_cvode, Jac);
	if (check_flag(&flag, "CVDlsSetDenseJacFn", 1)) return(1);
	
	/* In loop, call CVode, print results, and test for error.
     Break out of loop when NOUT preset output times have been reached.  */
	
	tout = T0+params.time_step();
	err_code = 0;
	int mode = 0;
	int	num_res_vals = params.num_eqs()*params.num_blocks();
	while(t+tbase < params.end_time()) {
		switch (mode) {
			case 0:
				current_cvode = long_term_cvode;
				break;
			case 1:
				current_cvode = event_cvode;
				break;
		}
		flag = CVode(current_cvode, tout, y, &t, CV_NORMAL);
		record_results(results, y, t, tbase, num_res_vals);
		
		if (check_flag(&flag, "CVode", 1)) {
			err_code = flag;
			break;
		}
		if (flag == CV_ROOT_RETURN) {
			int flagr;
			int rootsfound[params.num_blocks()];
			flagr = CVodeGetRootInfo(current_cvode, rootsfound);
			if (check_flag(&flagr, "CVodeGetRootInfo", 1)) return(1);
			//mode = !mode;
			//std::cerr << rootsfound[0] << std::endl;
		}
		if (flag == CV_SUCCESS) tout += params.time_step();
		if (t > 10) {
			t -= 10;
			tout -= 10;
			Xth(y,0) -= 10;
			tbase += 10;
			CVodeReInit(current_cvode, t, y);
		}
	}
	
	std::cerr << err_code <<
		" X:" << Xth(y,0) <<
		" V:" << Vth(y,0) <<
		" H:" << Hth(y,0) <<
		" F:" << F(0,Vth(y,0),Hth(y,0),params) <<
		" dV:" << (Xth(y,0)-t-params.param(0, K_PARAM)*F(0,Vth(y,0),Hth(y,0),params))/params.param(0, R_PARAM) <<
		" dH:" << -Hth(y,0)*Vth(y,0)*log(Hth(y,0)*Vth(y,0)) << std::endl;
	/* Print some final statistics */
	//PrintFinalStats(cvode_mem);
	
	/* Free y and abstol vectors */
	N_VDestroy_Serial(y);
	N_VDestroy_Serial(long_term_abstol);
	N_VDestroy_Serial(event_abstol);
	
	/* Free integrator memory */
	CVodeFree(&long_term_cvode);
	
	return err_code;
}
Exemple #16
0
int jmi_ode_cvode_new(jmi_ode_cvode_t** integrator_ptr, jmi_ode_solver_t* solver) {
    jmi_ode_cvode_t* integrator;
    jmi_ode_problem_t* problem = solver -> ode_problem;
    int flag = 0;
    void* cvode_mem;
    jmi_real_t* y;
    jmi_real_t* atol_nv;
    int i;
    
    integrator = (jmi_ode_cvode_t*)calloc(1,sizeof(jmi_ode_cvode_t));
    if(!integrator){
        jmi_log_node(problem->log, logError, "Error", "Failed to allocate the internal CVODE struct.");
        return -1;
    }

    /* DEFAULT VALUES NEEDS TO BE IMPROVED*/
    integrator->lmm  = CV_BDF;
    integrator->iter = CV_NEWTON;
    /* integrator->rtol = 1e-4; */
    integrator->rtol = solver->rel_tol;
    
    if (problem->n_real_x > 0) {
        integrator->atol = N_VNew_Serial(problem->n_real_x);
    } else {
        integrator->atol = N_VNew_Serial(1);
    }
    atol_nv = NV_DATA_S(integrator->atol);
    
    if (problem->n_real_x > 0) {
        for (i = 0; i < problem->n_real_x; i++) {
            atol_nv[i] = 0.01*integrator->rtol*problem->nominal[i];
        }
    }else{
        atol_nv[0] = 0.01*integrator->rtol*1.0;
    }

    cvode_mem = CVodeCreate(integrator->lmm,integrator->iter);
    if(!cvode_mem){
        jmi_log_node(problem->log, logError, "Error", "Failed to allocate the CVODE struct.");
        return -1;
    }

    /* Get the default values for the time and states */
    if (problem->n_real_x > 0) {
        integrator->y_work = N_VNew_Serial(problem->n_real_x);
        y = NV_DATA_S(integrator->y_work);
		memcpy (y, problem->states, problem->n_real_x*sizeof(jmi_real_t));
    }else{
        integrator->y_work = N_VNew_Serial(1);
        y = NV_DATA_S(integrator->y_work);
        y[0] = 0.0;
    }
    
    flag = CVodeInit(cvode_mem, cv_rhs, problem->time, integrator->y_work);
    if(flag != 0) {
        jmi_log_node(problem->log, logError, "Error", "Failed to initialize CVODE. Returned with <error_flag: %d>", flag);
        return -1;
    }

    flag = CVodeSVtolerances(cvode_mem, integrator->rtol, integrator->atol);
    if(flag!=0){
        jmi_log_node(problem->log, logError, "Error", "Failed to specify the tolerances. Returned with <error_flag: %d>", flag);
        return -1;
    }

    if (problem->n_real_x > 0) {
        flag = CVDense(cvode_mem, problem->n_real_x);
    }else{
        flag = CVDense(cvode_mem, 1);
    }
    if(flag!=0){
        jmi_log_node(problem->log, logError, "Error", "Failed to specify the linear solver. Returned with <error_flag: %d>", flag);
        return -1;
    }

    flag = CVodeSetUserData(cvode_mem, (void*)solver);
    if(flag!=0){
        jmi_log_node(problem->log, logError, "Error", "Failed to specify the user data. Returned with <error_flag: %d>", flag);
        return -1;
    }
    
    if (problem->n_sw > 0){
        flag = CVodeRootInit(cvode_mem, problem->n_sw, cv_root);
        if(flag!=0){
            jmi_log_node(problem->log, logError, "Error", "Failed to specify the event indicator function. Returned with <error_flag: %d>", flag);
            return -1;
        }
    }
    
    flag = CVodeSetErrHandlerFn(cvode_mem, cv_err, (void*)solver);
    if(flag!=0){
        jmi_log_node(problem->log, logError, "Error", "Failed to specify the error handling function. Returned with <error_flag: %d>", flag);
        return -1;
    }

    integrator->cvode_mem = cvode_mem;    
      
    *integrator_ptr = integrator;
    return 0;
}
void CVodesIntegrator::initialize(double t0, FuncEval& func)
{
    m_neq = func.neq();
    m_t0 = t0;
    m_time = t0;

    if (m_y) {
        N_VDestroy_Serial(m_y); // free solution vector if already allocated
    }
    m_y = N_VNew_Serial(static_cast<sd_size_t>(m_neq)); // allocate solution vector
    N_VConst(0.0, m_y);
    // check abs tolerance array size
    if (m_itol == CV_SV && m_nabs < m_neq) {
        throw CanteraError("CVodesIntegrator::initialize",
                           "not enough absolute tolerance values specified.");
    }

    func.getState(NV_DATA_S(m_y));

    if (m_cvode_mem) {
        CVodeFree(&m_cvode_mem);
    }

    //! Specify the method and the iteration type. Cantera Defaults:
    //!        CV_BDF  - Use BDF methods
    //!        CV_NEWTON - use Newton's method
    m_cvode_mem = CVodeCreate(m_method, m_iter);
    if (!m_cvode_mem) {
        throw CanteraError("CVodesIntegrator::initialize",
                           "CVodeCreate failed.");
    }

    int flag = CVodeInit(m_cvode_mem, cvodes_rhs, m_t0, m_y);
    if (flag != CV_SUCCESS) {
        if (flag == CV_MEM_FAIL) {
            throw CanteraError("CVodesIntegrator::initialize",
                               "Memory allocation failed.");
        } else if (flag == CV_ILL_INPUT) {
            throw CanteraError("CVodesIntegrator::initialize",
                               "Illegal value for CVodeInit input argument.");
        } else {
            throw CanteraError("CVodesIntegrator::initialize",
                               "CVodeInit failed.");
        }
    }
    CVodeSetErrHandlerFn(m_cvode_mem, &cvodes_err, this);

    if (m_itol == CV_SV) {
        flag = CVodeSVtolerances(m_cvode_mem, m_reltol, m_abstol);
    } else {
        flag = CVodeSStolerances(m_cvode_mem, m_reltol, m_abstols);
    }
    if (flag != CV_SUCCESS) {
        if (flag == CV_MEM_FAIL) {
            throw CanteraError("CVodesIntegrator::initialize",
                               "Memory allocation failed.");
        } else if (flag == CV_ILL_INPUT) {
            throw CanteraError("CVodesIntegrator::initialize",
                               "Illegal value for CVodeInit input argument.");
        } else {
            throw CanteraError("CVodesIntegrator::initialize",
                               "CVodeInit failed.");
        }
    }

    flag = CVodeSetUserData(m_cvode_mem, &func);
    if (flag != CV_SUCCESS) {
        throw CanteraError("CVodesIntegrator::initialize",
                           "CVodeSetUserData failed.");
    }
    if (func.nparams() > 0) {
        sensInit(t0, func);
        flag = CVodeSetSensParams(m_cvode_mem, func.m_sens_params.data(),
                                  func.m_paramScales.data(), NULL);
        if (flag != CV_SUCCESS) {
            throw CanteraError("CVodesIntegrator::initialize",
                               "CVodeSetSensParams failed.");
        }
    }
    applyOptions();
}