Exemplo n.º 1
0
int cvode_eval(solver_props *props, unsigned int modelid){
  cvode_mem *mem = props->mem;
  mem = &mem[modelid];

  // Stop the solver if the stop time has been reached
  props->running[modelid] = (props->time[modelid] + props->timestep) < props->stoptime;
  if(!props->running[modelid])
    return 0;

  // if a positive dt is specified, then we will have this function return after it reaches the next time point,
  // otherwise, it will just run one iteration and return
  if(props->timestep > 0) {
    // Reinitialize the function at each step
    if(CVodeReInit(mem->cvmem, props->time[modelid], mem->y0) != CV_SUCCESS) {
      PRINTF( "CVODE failed to reinitialize");
    }

    CDATAFORMAT stop_time = MIN(props->time[modelid] + props->timestep, props->stoptime);
    mem->first_iteration = TRUE;
    if(CVode(mem->cvmem, stop_time, mem->y0, &(props->next_time[modelid]), CV_NORMAL) != CV_SUCCESS){
      PRINTF( "CVODE failed to make a fixed step in model %d.\n", modelid);
      return 1;
    }
  }
  else {
    mem->first_iteration = TRUE;
    if(CVode(mem->cvmem, props->stoptime, mem->y0, &(props->next_time[modelid]), CV_ONE_STEP) != CV_SUCCESS){
      PRINTF( "CVODE failed to make a step in model %d.\n", modelid);
      return 1;
    }
  }

  return 0;
}
Exemplo n.º 2
0
void ode_solver_reinit(ode_solver* solver, const double t0,  double* y0, int lenY,  const double* p, int lenP ){
  int i,flag;
  
  /* Get initial conditions */
  if(y0 != 0){
    if( lenY != solver->odeModel->N ){
      fprintf(stderr,"ode_solver_init: lenY must be equal %d, the number of variables in the ode model.\n",solver->odeModel->N);
      return ;
    }
    NV_DATA_S(solver->y) = y0;
  }
  else {
    NV_DATA_S(solver->y) = solver->odeModel->v;
  }
  
  
  /* re-initialise */
  flag = CVodeReInit(solver->cvode_mem, t0, solver->y);
  
  /* Get parameters */
  if (p != 0){
    if (lenP != solver->odeModel->P) {
      fprintf(stderr,"ode_solver_init: lenP must be equal %d, the number of parameters in the ode model.\n",solver->odeModel->P);
      return ;
    }
    int P = solver->odeModel->P;
    for(i = 0; i < P; i++)
      solver->params[i] = p[i];
		
    flag = CVodeSetUserData(solver->cvode_mem, solver->params);
  }
  
}
Exemplo n.º 3
0
int CVodeReInitB(void *cvadj_mem, CVRhsFnB fB, 
                 realtype tB0, N_Vector yB0, 
                 int itolB, realtype reltolB, void *abstolB)
{
  CVadjMem ca_mem;
  void *cvode_mem;
  int sign, flag;

  if (cvadj_mem == NULL) return(CV_ADJMEM_NULL);

  ca_mem = (CVadjMem) cvadj_mem;

  sign = (tfinal - tinitial > ZERO) ? 1 : -1;
  if ( (sign*(tB0-tinitial) < ZERO) || (sign*(tfinal-tB0) < ZERO) )
    return(CV_BAD_TB0);
  
  f_B  = fB;

  cvode_mem = (void *) ca_mem->cvb_mem;

  flag = CVodeReInit(cvode_mem, CVArhs, tB0, yB0,
                     itolB, reltolB, abstolB);

  if (flag != CV_SUCCESS) return(flag);

  CVodeSetMaxHnilWarns(cvode_mem, -1);
  CVodeSetFdata(cvode_mem, cvadj_mem);

  return(CV_SUCCESS);

}
Exemplo n.º 4
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 CVodesIntegrator::reinitialize(double t0, FuncEval& func)
{
    m_t0 = t0;
    m_time = t0;
    func.getState(NV_DATA_S(m_y));

    int result = CVodeReInit(m_cvode_mem, m_t0, m_y);
    if (result != CV_SUCCESS) {
        throw CanteraError("CVodesIntegrator::reinitialize",
                           "CVodeReInit failed. result = {}", result);
    }
    applyOptions();
}
Exemplo n.º 6
0
void CVodesIntegrator::reinitialize(double t0, FuncEval& func)
{
    m_t0 = t0;
    m_time = t0;
    func.getInitialConditions(m_t0, static_cast<sd_size_t>(m_neq),
                              NV_DATA_S(m_y));

    int result;
    result = CVodeReInit(m_cvode_mem, m_t0, m_y);
    if (result != CV_SUCCESS) {
        throw CVodesErr("CVodeReInit failed. result = "+int2str(result));
    }
    applyOptions();
}
Exemplo n.º 7
0
  void CVodesIntegrator::reinitialize(double t0, FuncEval& func) 
  {
    m_t0  = t0;
    //try {
    func.getInitialConditions(m_t0, m_neq, NV_DATA_S(nv(m_y)));
    //}
    //catch (CanteraError) {
    //showErrors();
    //error("Teminating execution");
    //}

    int result, flag;

#if defined(SUNDIALS_VERSION_22) || defined(SUNDIALS_VERSION_23)
    if (m_itol == CV_SV) {
      result = CVodeReInit(m_cvode_mem, cvodes_rhs, m_t0, nv(m_y), 
			   m_itol, m_reltol,
			   nv(m_abstol));
    }
    else {
      result = CVodeReInit(m_cvode_mem, cvodes_rhs, m_t0, nv(m_y),
			   m_itol, m_reltol,
			   &m_abstols);
    }
    if (result != CV_SUCCESS) { 
      throw CVodesErr("CVodeReInit failed. result = "+int2str(result));
    }
#elif defined(SUNDIALS_VERSION_24)
    result = CVodeReInit(m_cvode_mem, m_t0, nv(m_y));
    if (result != CV_SUCCESS) { 
      throw CVodesErr("CVodeReInit failed. result = "+int2str(result));
    }
#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 == 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 if (m_type == GMRES) {
      CVSpgmr(m_cvode_mem, PREC_NONE, 0);
    }
    else {
      throw CVodesErr("unsupported option");
    }


    // 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);
  }
Exemplo n.º 8
0
bool Bloch_McConnell_CV_Model::Calculate(double next_tStop){
	
	if ( m_world->time < RTOL)
	    m_world->time += RTOL;
	
	CVodeSetStopTime(m_cvode_mem,next_tStop);
	cout<<NV_Ith_S( ((bmnvec*) (m_world->solverSettings))->y,ZC ) << " "<< NV_Ith_S( ((bmnvec*) (m_world->solverSettings))->y,ZC+3 )<<endl;
	
	int flag;
#ifndef CVODE26
	flag = CVode(m_cvode_mem, m_world->time, ((bmnvec*) (m_world->solverSettings))->y, &m_tpoint, CV_NORMAL_TSTOP);
#else
	do {
		flag=CVode(m_cvode_mem, m_world->time, ((bmnvec*) (m_world->solverSettings))->y, &m_tpoint, CV_NORMAL);
	} while ((flag==CV_TSTOP_RETURN) && (m_world->time-TIME_ERR_TOL > m_tpoint ));
	
#endif
	if(flag < 0) 
		m_world->solverSuccess=false;
	
	//reinit needed?
	if ( m_world->phase == -2.0 && m_world->solverSuccess ) {

#ifndef CVODE26
		CVodeReInit(m_cvode_mem,bloch,m_world->time + TIME_ERR_TOL,((bmnvec*) (m_world->solverSettings))->y,CV_SV,m_reltol,((bmnvec*) (m_world->solverSettings))->abstol);
#else
		CVodeReInit(m_cvode_mem,m_world->time + TIME_ERR_TOL,((bmnvec*) (m_world->solverSettings))->y);
#endif
		// avoiding warnings: (no idea why initial guess of steplength does not work right here...)
		CVodeSetInitStep(m_cvode_mem,m_world->pAtom->GetDuration()/1e9);

	}



    // loop over pools, stepsize NEQ
    for ( int i = 0; i< m_ncomp*NEQ; i+=NEQ ) {
		
    	double solution_dummy_x = NV_Ith_S(((bmnvec*) (m_world->solverSettings))->y, XC+i );
    	double solution_dummy_y = NV_Ith_S(((bmnvec*) (m_world->solverSettings))->y, YC+i );
		
    	m_world->solution[AMPL+i]  = sqrt(solution_dummy_x*solution_dummy_x + solution_dummy_y*solution_dummy_y);
		
       	if (m_world->solution[AMPL+i] < EPS)
    		m_world->solution[PHASE+i] = 0;
    	else
    		if (solution_dummy_y < 0 )
   				m_world->solution[PHASE+i] = 2*PI - acos(solution_dummy_x / m_world->solution[AMPL+i]);
    		else
    			m_world->solution[PHASE+i] =        acos(solution_dummy_x / m_world->solution[AMPL+i]);
		
    	m_world->solution[ZC+i]    = NV_Ith_S(((bmnvec*) (m_world->solverSettings))->y, ZC+i );

    	// Kaveh, hier sind dann alle pools gleich :(
        //cout << "          bloch solution "<<m_world->solution[ZC+i]<< "      "    <<" i " << i <<endl;
    }


	//higher accuray than 1e-10 not useful. Return success and hope for the best.
	if(m_reltol < 1e-10) 
		m_world->solverSuccess=true;
	
	return m_world->solverSuccess;

}
Exemplo n.º 9
0
int main()
{
  realtype abstol, reltol, t, tout;
  N_Vector u;
  UserData data;
  void *cvode_mem;
  int flag, iout, jpre;
  long int ml, mu;

  u = NULL;
  data = NULL;
  cvode_mem = NULL;

  /* Allocate and initialize u, and set problem data and tolerances */ 
  u = N_VNew_Serial(NEQ);
  if(check_flag((void *)u, "N_VNew_Serial", 0)) return(1);
  data = (UserData) malloc(sizeof *data);
  if(check_flag((void *)data, "malloc", 2)) return(1);
  InitUserData(data);
  SetInitialProfiles(u, data->dx, data->dy);
  abstol = ATOL; 
  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);

  /* Set the pointer to user-defined data */
  flag = CVodeSetUserData(cvode_mem, data);
  if(check_flag(&flag, "CVodeSetUserData", 1)) return(1);

  /* Call CVodeInit to initialize the integrator memory and specify the
   * user's right hand side function in u'=f(t,u), the inital time T0, and
   * the initial dependent variable vector u. */
  flag = CVodeInit(cvode_mem, f, T0, u);
  if(check_flag(&flag, "CVodeInit", 1)) return(1);

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

  /* Call CVSpgmr to specify the linear solver CVSPGMR 
     with left preconditioning and the maximum Krylov dimension maxl */
  flag = CVSpgmr(cvode_mem, PREC_LEFT, 0);
  if(check_flag(&flag, "CVSpgmr", 1)) return(1);

  /* Call CVBandPreInit to initialize band preconditioner */
  ml = mu = 2;
  flag = CVBandPrecInit(cvode_mem, NEQ, mu, ml);
  if(check_flag(&flag, "CVBandPrecInit", 0)) return(1);

  PrintIntro(mu, ml);

  /* Loop over jpre (= PREC_LEFT, PREC_RIGHT), and solve the problem */

  for (jpre = PREC_LEFT; jpre <= PREC_RIGHT; jpre++) {
    
    /* On second run, re-initialize u, the solver, and CVSPGMR */
    
    if (jpre == PREC_RIGHT) {
      
      SetInitialProfiles(u, data->dx, data->dy);
      
      flag = CVodeReInit(cvode_mem, T0, u);
      if(check_flag(&flag, "CVodeReInit", 1)) return(1);

      flag = CVSpilsSetPrecType(cvode_mem, PREC_RIGHT);
      check_flag(&flag, "CVSpilsSetPrecType", 1);
      
      printf("\n\n-------------------------------------------------------");
      printf("------------\n");
    }
    
    printf("\n\nPreconditioner type is:  jpre = %s\n\n",
           (jpre == PREC_LEFT) ? "PREC_LEFT" : "PREC_RIGHT");
    
    /* In loop over output points, call CVode, print results, test for error */
    
    for (iout = 1, tout = TWOHR; iout <= NOUT; iout++, tout += TWOHR) {
      flag = CVode(cvode_mem, tout, u, &t, CV_NORMAL);
      check_flag(&flag, "CVode", 1);
      PrintOutput(cvode_mem, u, t);
      if (flag != CV_SUCCESS) {
        break;
      }
    }
    
    /* Print final statistics */
    
    PrintFinalStats(cvode_mem);
    
  } /* End of jpre loop */

  /* Free memory */
  N_VDestroy_Serial(u);
  free(data);
  CVodeFree(&cvode_mem);

  return(0);
}
Exemplo n.º 10
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;
}
Exemplo n.º 11
0
static int Problem1(void)
{
  realtype reltol=RTOL, abstol=ATOL, t, tout, ero, er;
  int miter, flag, temp_flag, iout, nerr=0;
  N_Vector y;
  void *cvode_mem;
  booleantype firstrun;
  int qu;
  realtype hu;

  y = NULL;
  cvode_mem = NULL;

  y = N_VNew_Serial(P1_NEQ);
  if(check_flag((void *)y, "N_VNew_Serial", 0)) return(1);
  PrintIntro1();

  cvode_mem = CVodeCreate(CV_ADAMS, CV_FUNCTIONAL);
  if(check_flag((void *)cvode_mem, "CVodeCreate", 0)) return(1);

  for (miter=FUNC; miter <= DIAG; miter++) {
    ero = ZERO;
    NV_Ith_S(y,0) = TWO;
    NV_Ith_S(y,1) = ZERO;

    firstrun = (miter==FUNC);
    if (firstrun) {
      flag = CVodeMalloc(cvode_mem, f1, P1_T0, y, CV_SS, reltol, &abstol);
      if(check_flag(&flag, "CVodeMalloc", 1)) return(1);
    } else {
      flag = CVodeSetIterType(cvode_mem, CV_NEWTON);
      if(check_flag(&flag, "CVodeSetIterType", 1)) ++nerr;
      flag = CVodeReInit(cvode_mem, f1, P1_T0, y, CV_SS, reltol, &abstol);
      if(check_flag(&flag, "CVodeReInit", 1)) return(1);
    }
      
    flag = PrepareNextRun(cvode_mem, CV_ADAMS, miter, 0, 0);
    if(check_flag(&flag, "PrepareNextRun", 1)) return(1);

    PrintHeader1();

    for(iout=1, tout=P1_T1; iout <= P1_NOUT; iout++, tout += P1_DTOUT) {
      flag = CVode(cvode_mem, tout, y, &t, CV_NORMAL);
      check_flag(&flag, "CVode", 1);
      temp_flag = CVodeGetLastOrder(cvode_mem, &qu);
      if(check_flag(&temp_flag, "CVodeGetLastOrder", 1)) ++nerr;
      temp_flag = CVodeGetLastStep(cvode_mem, &hu);
      if(check_flag(&temp_flag, "CVodeGetLastStep", 1)) ++nerr;
      PrintOutput1(t, NV_Ith_S(y,0), NV_Ith_S(y,1), qu, hu);
      if (flag != CV_SUCCESS) {
        nerr++;
        break;
      }
      if (iout%2 == 0) {
        er = ABS(NV_Ith_S(y,0)) / abstol;
        if (er > ero) ero = er;
        if (er > P1_TOL_FACTOR) {
          nerr++;
	  PrintErrOutput(P1_TOL_FACTOR);
        }
      }
    }
    
    PrintFinalStats(cvode_mem, miter, ero);
  }

  CVodeFree(cvode_mem);

  cvode_mem = CVodeCreate(CV_BDF, CV_FUNCTIONAL);
  if(check_flag((void *)cvode_mem, "CVodeCreate", 0)) return(1);

  for (miter=FUNC; miter <= DIAG; miter++) {
    ero = ZERO;
    NV_Ith_S(y,0) = TWO;
    NV_Ith_S(y,1) = ZERO;
      
    firstrun = (miter==FUNC);
    if (firstrun) {
      flag = CVodeMalloc(cvode_mem, f1, P1_T0, y, CV_SS, reltol, &abstol);
      if(check_flag(&flag, "CVodeMalloc", 1)) return(1);
    } else {
      flag = CVodeSetIterType(cvode_mem, CV_NEWTON);
      if(check_flag(&flag, "CVodeSetIterType", 1)) ++nerr;
      flag = CVodeReInit(cvode_mem, f1, P1_T0, y, CV_SS, reltol, &abstol);
      if(check_flag(&flag, "CVodeReInit", 1)) return(1);
    }
      
    flag = PrepareNextRun(cvode_mem, CV_BDF, miter, 0, 0);     
    if(check_flag(&flag, "PrepareNextRun", 1)) return(1);

    PrintHeader1();
      
    for(iout=1, tout=P1_T1; iout <= P1_NOUT; iout++, tout += P1_DTOUT) {
      flag = CVode(cvode_mem, tout, y, &t, CV_NORMAL);
      check_flag(&flag, "CVode", 1);
      temp_flag = CVodeGetLastOrder(cvode_mem, &qu);
      if(check_flag(&temp_flag, "CVodeGetLastOrder", 1)) ++nerr;
      temp_flag = CVodeGetLastStep(cvode_mem, &hu);
      if(check_flag(&temp_flag, "CVodeGetLastStep", 1)) ++nerr;
      PrintOutput1(t, NV_Ith_S(y,0), NV_Ith_S(y,1), qu, hu);
      if (flag != CV_SUCCESS) {
        nerr++;
        break;
      }
      if (iout%2 == 0) {
        er = ABS(NV_Ith_S(y,0)) / abstol;
        if (er > ero) ero = er;
        if (er > P1_TOL_FACTOR) {
          nerr++;
          PrintErrOutput(P1_TOL_FACTOR);
        }
      }
    }
    
    PrintFinalStats(cvode_mem, miter, ero);
  }

  CVodeFree(cvode_mem);
  N_VDestroy_Serial(y);

  return(nerr);
}
Exemplo n.º 12
0
void CvodeSolver::initialize(const double &pVoiStart,
                             const int &pRatesStatesCount, double *pConstants,
                             double *pRates, double *pStates,
                             double *pAlgebraic,
                             ComputeRatesFunction pComputeRates)
{
    if (!mSolver) {
        // Retrieve some of the CVODE properties

        double maximumStep = MaximumStepDefaultValue;
        int maximumNumberOfSteps = MaximumNumberOfStepsDefaultValue;
        QString integrationMethod = IntegrationMethodDefaultValue;
        QString iterationType = IterationTypeDefaultValue;
        QString linearSolver = LinearSolverDefaultValue;
        QString preconditioner = PreconditionerDefaultValue;
        int upperHalfBandwidth = UpperHalfBandwidthDefaultValue;
        int lowerHalfBandwidth = LowerHalfBandwidthDefaultValue;
        double relativeTolerance = RelativeToleranceDefaultValue;
        double absoluteTolerance = AbsoluteToleranceDefaultValue;

        if (mProperties.contains(MaximumStepId)) {
            maximumStep = mProperties.value(MaximumStepId).toDouble();
        } else {
            emit error(QObject::tr("the 'maximum step' property value could not be retrieved"));

            return;
        }

        if (mProperties.contains(MaximumNumberOfStepsId)) {
            maximumNumberOfSteps = mProperties.value(MaximumNumberOfStepsId).toInt();
        } else {
            emit error(QObject::tr("the 'maximum number of steps' property value could not be retrieved"));

            return;
        }

        if (mProperties.contains(IntegrationMethodId)) {
            integrationMethod = mProperties.value(IntegrationMethodId).toString();
        } else {
            emit error(QObject::tr("the 'integration method' property value could not be retrieved"));

            return;
        }

        if (mProperties.contains(IterationTypeId)) {
            iterationType = mProperties.value(IterationTypeId).toString();

            if (!iterationType.compare(NewtonIteration)) {
                // We are dealing with a Newton iteration, so retrieve and check
                // its linear solver

                if (mProperties.contains(LinearSolverId)) {
                    linearSolver = mProperties.value(LinearSolverId).toString();

                    bool needUpperAndLowerHalfBandwidths = false;

                    if (   !linearSolver.compare(DenseLinearSolver)
                        || !linearSolver.compare(DiagonalLinearSolver)) {
                        // We are dealing with a dense/diagonal linear solver,
                        // so nothing more to do
                    } else if (!linearSolver.compare(BandedLinearSolver)) {
                        // We are dealing with a banded linear solver, so we
                        // need both an upper and a lower half bandwidth

                        needUpperAndLowerHalfBandwidths = true;
                    } else {
                        // We are dealing with a GMRES/Bi-CGStab/TFQMR linear
                        // solver, so retrieve and check its preconditioner

                        if (mProperties.contains(PreconditionerId)) {
                            preconditioner = mProperties.value(PreconditionerId).toString();
                        } else {
                            emit error(QObject::tr("the 'preconditioner' property value could not be retrieved"));

                            return;
                        }

                        if (!preconditioner.compare(BandedPreconditioner)) {
                            // We are dealing with a banded preconditioner, so
                            // we need both an upper and a lower half bandwidth

                            needUpperAndLowerHalfBandwidths = true;
                        }
                    }

                    if (needUpperAndLowerHalfBandwidths) {
                        if (mProperties.contains(UpperHalfBandwidthId)) {
                            upperHalfBandwidth = mProperties.value(UpperHalfBandwidthId).toInt();

                            if (   (upperHalfBandwidth < 0)
                                || (upperHalfBandwidth >= pRatesStatesCount)) {
                                emit error(QObject::tr("the 'upper half-bandwidth' property must have a value between 0 and %1").arg(pRatesStatesCount-1));

                                return;
                            }
                        } else {
                            emit error(QObject::tr("the 'upper half-bandwidth' property value could not be retrieved"));

                            return;
                        }

                        if (mProperties.contains(LowerHalfBandwidthId)) {
                            lowerHalfBandwidth = mProperties.value(LowerHalfBandwidthId).toInt();

                            if (   (lowerHalfBandwidth < 0)
                                || (lowerHalfBandwidth >= pRatesStatesCount)) {
                                emit error(QObject::tr("the 'lower half-bandwidth' property must have a value between 0 and %1").arg(pRatesStatesCount-1));

                                return;
                            }
                        } else {
                            emit error(QObject::tr("the 'lower half-bandwidth' property value could not be retrieved"));

                            return;
                        }
                    }
                } else {
                    emit error(QObject::tr("the 'linear solver' property value could not be retrieved"));

                    return;
                }
            }
        } else {
            emit error(QObject::tr("the 'iteration type' property value could not be retrieved"));

            return;
        }

        if (mProperties.contains(RelativeToleranceId)) {
            relativeTolerance = mProperties.value(RelativeToleranceId).toDouble();

            if (relativeTolerance < 0) {
                emit error(QObject::tr("the 'relative tolerance' property must have a value greater than or equal to 0"));

                return;
            }
        } else {
            emit error(QObject::tr("the 'relative tolerance' property value could not be retrieved"));

            return;
        }

        if (mProperties.contains(AbsoluteToleranceId)) {
            absoluteTolerance = mProperties.value(AbsoluteToleranceId).toDouble();

            if (absoluteTolerance < 0) {
                emit error(QObject::tr("the 'absolute tolerance' property must have a value greater than or equal to 0"));

                return;
            }
        } else {
            emit error(QObject::tr("the 'absolute tolerance' property value could not be retrieved"));

            return;
        }

        if (mProperties.contains(InterpolateSolutionId)) {
            mInterpolateSolution = mProperties.value(InterpolateSolutionId).toBool();
        } else {
            emit error(QObject::tr("the 'interpolate solution' property value could not be retrieved"));

            return;
        }

        // Initialise the ODE solver itself

        OpenCOR::Solver::OdeSolver::initialize(pVoiStart, pRatesStatesCount,
                                               pConstants, pRates, pStates,
                                               pAlgebraic, pComputeRates);

        // Create the states vector

        mStatesVector = N_VMake_Serial(pRatesStatesCount, pStates);

        // Create the CVODE solver

        bool newtonIteration = !iterationType.compare(NewtonIteration);

        mSolver = CVodeCreate(!integrationMethod.compare(BdfMethod)?CV_BDF:CV_ADAMS,
                              newtonIteration?CV_NEWTON:CV_FUNCTIONAL);

        // Use our own error handler

        CVodeSetErrHandlerFn(mSolver, errorHandler, this);

        // Initialise the CVODE solver

        CVodeInit(mSolver, rhsFunction, pVoiStart, mStatesVector);

        // Set some user data

        mUserData = new CvodeSolverUserData(pConstants, pAlgebraic,
                                            pComputeRates);

        CVodeSetUserData(mSolver, mUserData);

        // Set the maximum step

        CVodeSetMaxStep(mSolver, maximumStep);

        // Set the maximum number of steps

        CVodeSetMaxNumSteps(mSolver, maximumNumberOfSteps);

        // Set the linear solver, if needed

        if (newtonIteration) {
            if (!linearSolver.compare(DenseLinearSolver)) {
                CVDense(mSolver, pRatesStatesCount);
            } else if (!linearSolver.compare(BandedLinearSolver)) {
                CVBand(mSolver, pRatesStatesCount, upperHalfBandwidth, lowerHalfBandwidth);
            } else if (!linearSolver.compare(DiagonalLinearSolver)) {
                CVDiag(mSolver);
            } else {
                // We are dealing with a GMRES/Bi-CGStab/TFQMR linear solver

                if (!preconditioner.compare(BandedPreconditioner)) {
                    if (!linearSolver.compare(GmresLinearSolver))
                        CVSpgmr(mSolver, PREC_LEFT, 0);
                    else if (!linearSolver.compare(BiCgStabLinearSolver))
                        CVSpbcg(mSolver, PREC_LEFT, 0);
                    else
                        CVSptfqmr(mSolver, PREC_LEFT, 0);

                    CVBandPrecInit(mSolver, pRatesStatesCount, upperHalfBandwidth, lowerHalfBandwidth);
                } else {
                    if (!linearSolver.compare(GmresLinearSolver))
                        CVSpgmr(mSolver, PREC_NONE, 0);
                    else if (!linearSolver.compare(BiCgStabLinearSolver))
                        CVSpbcg(mSolver, PREC_NONE, 0);
                    else
                        CVSptfqmr(mSolver, PREC_NONE, 0);
                }
            }
        }

        // Set the relative and absolute tolerances

        CVodeSStolerances(mSolver, relativeTolerance, absoluteTolerance);
    } else {
        // Reinitialise the CVODE object

        CVodeReInit(mSolver, pVoiStart, mStatesVector);
    }
}
Exemplo n.º 13
0
int main()
{
  void *cvode_mem;
  SUNMatrix A;
  SUNLinearSolver LS;

  N_Vector y;
  int flag, ret;
  realtype reltol, abstol, t0, t1, t2, t;
  long int nst1, nst2, nst;

  reltol = RCONST(1.0e-3);
  abstol = RCONST(1.0e-4);

  t0 = RCONST(0.0);
  t1 = RCONST(1.0);
  t2 = RCONST(2.0);

  /* Allocate the vector of initial conditions */
  y = N_VNew_Serial(NEQ);

  /* Set initial condition */
  NV_Ith_S(y,0) = RCONST(1.0);

  /*
   * ------------------------------------------------------------
   *  Shared initialization and setup
   * ------------------------------------------------------------
   */

  /* Call CVodeCreate to create CVODE memory block and specify the
   * Backward Differentiaion Formula */
  cvode_mem = CVodeCreate(CV_BDF);
  if (check_flag((void *)cvode_mem, "CVodeCreate", 0)) return(1);

  /* Call CVodeInit to initialize integrator memory and specify the
   * user's right hand side function y'=f(t,y), the initial time T0
   * and the initial condiition vector y. */
  ret = CVodeInit(cvode_mem, f, t0, y);
  if (check_flag((void *)&ret, "CVodeInit", 1)) return(1);

  /* Call CVodeSStolerances to specify integration tolereances,
   * specifically the scalar relative and absolute tolerance. */
  ret = CVodeSStolerances(cvode_mem, reltol, abstol);
  if (check_flag((void *)&ret, "CVodeSStolerances", 1)) return(1);

  /* Provide RHS flag as user data which can be access in user provided routines */
  ret = CVodeSetUserData(cvode_mem, &flag);
  if (check_flag((void *)&ret, "CVodeSetUserData", 1)) return(1);

  /* Create dense SUNMatrix for use in linear solver */
  A = SUNDenseMatrix(NEQ, NEQ);
  if (check_flag((void *)A, "SUNDenseMatrix", 0)) return(1);

  /* Create dense linear solver for use by CVode */
  LS = SUNLinSol_Dense(y, A);
  if (check_flag((void *)LS, "SUNLinSol_Dense", 0)) return(1);

  /* Attach the linear solver and matrix to CVode by calling CVodeSetLinearSolver */
  ret = CVodeSetLinearSolver(cvode_mem, LS, A);
  if (check_flag((void *)&ret, "CVodeSetLinearSolver", 1)) return(1);

  /*
   * ---------------------------------------------------------------
   * Discontinuity in the solution
   *
   * 1) Integrate to the discontinuity
   * 2) Integrate from the discontinuity
   * ---------------------------------------------------------------
   */

  /* ---- Integrate to the discontinuity */
 
  printf("\nDiscontinuity in solution\n\n");
 
  /* set TSTOP (max time solution proceeds to) - this is not required */
  ret = CVodeSetStopTime(cvode_mem, t1);
  if (check_flag((void *)&ret, "CVodeSetStopTime", 1)) return(1);

  flag = RHS1; /* use -y for RHS */
  t = t0; /* set the integrator start time */

  printf("%12.8e  %12.8e\n",t,NV_Ith_S(y,0));
  while (t<t1) {
    /* advance solver just one internal step */
    ret = CVode(cvode_mem, t1, y, &t, CV_ONE_STEP);
    if (check_flag((void *)&ret, "CVode", 1)) return(1);
    printf("%12.8e  %12.8e\n",t,NV_Ith_S(y,0));
  }
  /* Get the number of steps the solver took to get to the discont. */
  ret = CVodeGetNumSteps(cvode_mem, &nst1);
  if (check_flag((void *)&ret, "CvodeGetNumSteps", 1)) return(1);

  /* ---- Integrate from the discontinuity */

  /* Include discontinuity */
  NV_Ith_S(y,0) = RCONST(1.0);
 
  /* Reinitialize the solver */
  ret = CVodeReInit(cvode_mem, t1, y);
  if (check_flag((void *)&ret, "CVodeReInit", 1)) return(1);

  /* set TSTOP (max time solution proceeds to) - this is not required */
  ret = CVodeSetStopTime(cvode_mem, t2);
  if (check_flag((void *)&ret, "CVodeSetStopTime", 1)) return(1);

  flag = RHS1; /* use -y for RHS */
  t = t1; /* set the integrator start time */

  printf("%12.8e  %12.8e\n",t,NV_Ith_S(y,0));

  while (t<t2) {
    /* advance solver just one internal step */
    ret = CVode(cvode_mem, t2, y, &t, CV_ONE_STEP);
    if (check_flag((void *)&ret, "CVode", 1)) return(1);
    printf("%12.8e  %12.8e\n",t,NV_Ith_S(y,0));
  }

  /* Get the number of steps the solver took after the discont. */
  ret = CVodeGetNumSteps(cvode_mem, &nst2);
  if (check_flag((void *)&ret, "CvodeGetNumSteps", 1)) return(1);

  /* Print statistics */
  nst = nst1 + nst2;
  printf("\nNumber of steps: %ld + %ld = %ld\n",nst1, nst2, nst);

  /*
   * ---------------------------------------------------------------
   * Discontinuity in RHS: Case 1 - explicit treatment
   * Note that it is not required to set TSTOP, but without it
   * we would have to find y(t1) to reinitialize the solver.
   * ---------------------------------------------------------------
   */

  printf("\nDiscontinuity in RHS: Case 1 - explicit treatment\n\n");

  /* Set initial condition */
  NV_Ith_S(y,0) = RCONST(1.0);

  /* Reinitialize the solver. CVodeReInit does not reallocate memory
   * so it can only be used when the new problem size is the same as
   * the problem size when CVodeCreate was called. */
  ret = CVodeReInit(cvode_mem, t0, y);
  if (check_flag((void *)&ret, "CVodeReInit", 1)) return(1);

  /* ---- Integrate to the discontinuity */

  /* Set TSTOP (max time solution proceeds to) to location of discont. */
  ret = CVodeSetStopTime(cvode_mem, t1);
  if (check_flag((void *)&ret, "CVodeSetStopTime", 1)) return(1);

  flag = RHS1; /* use -y for RHS */
  t = t0; /* set the integrator start time */

  printf("%12.8e  %12.8e\n",t,NV_Ith_S(y,0));
  while (t<t1) {
    /* advance solver just one internal step */
    ret = CVode(cvode_mem, t1, y, &t, CV_ONE_STEP);
    if (check_flag((void *)&ret, "CVode", 1)) return(1);
    printf("%12.8e  %12.8e\n",t,NV_Ith_S(y,0));
  }

  /* Get the number of steps the solver took to get to the discont. */
  ret = CVodeGetNumSteps(cvode_mem, &nst1);
  if (check_flag((void *)&ret, "CvodeGetNumSteps", 1)) return(1);

  /* If TSTOP was not set, we'd need to find y(t1): */
  /* CVodeGetDky(cvode_mem, t1, 0, y); */

  /* ---- Integrate from the discontinuity */

  /* Reinitialize solver */
  ret = CVodeReInit(cvode_mem, t1, y);

  /* set TSTOP (max time solution proceeds to) - this is not required */
  ret = CVodeSetStopTime(cvode_mem, t2);
  if (check_flag((void *)&ret, "CVodeSetStopTime", 1)) return(1);

  flag = RHS2; /* use -5y for RHS */
  t = t1; /* set the integrator start time */

  printf("%12.8e  %12.8e\n",t,NV_Ith_S(y,0));

  while (t<t2) {
    /* advance solver just one internal step */
    ret = CVode(cvode_mem, t2, y, &t, CV_ONE_STEP);
    if (check_flag((void *)&ret, "CVode", 1)) return(1);
    printf("%12.8e  %12.8e\n",t,NV_Ith_S(y,0));
  }

  /* Get the number of steps the solver took after the discont. */
  ret = CVodeGetNumSteps(cvode_mem, &nst2);
  if (check_flag((void *)&ret, "CvodeGetNumSteps", 1)) return(1);

  /* Print statistics */
  nst = nst1 + nst2;
  printf("\nNumber of steps: %ld + %ld = %ld\n",nst1, nst2, nst);


  /*
   * ---------------------------------------------------------------
   * Discontinuity in RHS: Case 2 - let CVODE deal with it
   * Note that here we MUST set TSTOP to ensure that the
   * change in the RHS happens at the appropriate time
   * ---------------------------------------------------------------
   */

  printf("\nDiscontinuity in RHS: Case 2 - let CVODE deal with it\n\n");

  /* Set initial condition */
  NV_Ith_S(y,0) = RCONST(1.0);

  /* Reinitialize the solver. CVodeReInit does not reallocate memory
   * so it can only be used when the new problem size is the same as
   * the problem size when CVodeCreate was called. */
  ret = CVodeReInit(cvode_mem, t0, y);
  if (check_flag((void *)&ret, "CVodeReInit", 1)) return(1);

  /* ---- Integrate to the discontinuity */

  /* Set TSTOP (max time solution proceeds to) to location of discont. */
  ret = CVodeSetStopTime(cvode_mem, t1);
  if (check_flag((void *)&ret, "CVodeSetStopTime", 1)) return(1);

  flag = RHS1; /* use -y for RHS */
  t = t0; /* set the integrator start time */

  printf("%12.8e  %12.8e\n",t,NV_Ith_S(y,0));
  while (t<t1) {
    /* advance solver just one internal step */
    ret = CVode(cvode_mem, t1, y, &t, CV_ONE_STEP);
    if (check_flag((void *)&ret, "CVode", 1)) return(1);
    printf("%12.8e  %12.8e\n",t,NV_Ith_S(y,0));
  }

  /* Get the number of steps the solver took to get to the discont. */
  ret = CVodeGetNumSteps(cvode_mem, &nst1);
  if (check_flag((void *)&ret, "CvodeGetNumSteps", 1)) return(1);

  /* ---- Integrate from the discontinuity */

  /* set TSTOP (max time solution proceeds to) - this is not required */
  ret = CVodeSetStopTime(cvode_mem, t2);
  if (check_flag((void *)&ret, "CVodeSetStopTime", 1)) return(1);

  flag = RHS2; /* use -5y for RHS */
  t = t1; /* set the integrator start time */

  printf("%12.8e  %12.8e\n",t,NV_Ith_S(y,0));

  while (t<t2) {
    /* advance solver just one internal step */
    ret = CVode(cvode_mem, t2, y, &t, CV_ONE_STEP);
    if (check_flag((void *)&ret, "CVode", 1)) return(1);
    printf("%12.8e  %12.8e\n",t,NV_Ith_S(y,0));
  }

  /* Get the number of steps the solver took after the discont. */
  ret = CVodeGetNumSteps(cvode_mem, &nst);
  if (check_flag((void *)&ret, "CvodeGetNumSteps", 1)) return(1);

  /* Print statistics */
  nst2 = nst - nst1;
  printf("\nNumber of steps: %ld + %ld = %ld\n",nst1, nst2, nst);

  /* Free memory */
  N_VDestroy(y);
  SUNMatDestroy(A);
  SUNLinSolFree(LS);
  CVodeFree(&cvode_mem);

  return(0);
}
Exemplo n.º 14
0
void Cvode::CVodeCore()
{
  _idid = CVodeReInit(_cvodeMem, _tCurrent, _CV_y);
  _idid = CVodeSetStopTime(_cvodeMem, _tEnd);
  _idid = CVodeSetInitStep(_cvodeMem, 1e-12);
  if (_idid < 0)
    throw ModelicaSimulationError(SOLVER,"CVode::ReInit");

  bool writeEventOutput = (_settings->getGlobalSettings()->getOutputPointType() == OPT_ALL);
  bool writeOutput = !(_settings->getGlobalSettings()->getOutputPointType() == OPT_NONE);

  while ((_solverStatus & ISolver::CONTINUE) && !_interrupt )
  {
    _cv_rt = CVode(_cvodeMem, _tEnd, _CV_y, &_tCurrent, CV_ONE_STEP);

    _idid = CVodeGetNumSteps(_cvodeMem, &_locStps);
    if (_idid != CV_SUCCESS)
      throw ModelicaSimulationError(SOLVER,"CVodeGetNumSteps failed. The cvode mem pointer is NULL");

    _idid = CVodeGetLastStep(_cvodeMem, &_h);
    if (_idid != CV_SUCCESS)
      throw ModelicaSimulationError(SOLVER,"CVodeGetLastStep failed. The cvode mem pointer is NULL");

  //set completed step to system and check if terminate was called
    if(_continuous_system->stepCompleted(_tCurrent))
        _solverStatus = DONE;

    //Check if there was at least one output-point within the last solver interval
    //  -> Write output if true
    if (writeOutput)
    {
        writeCVodeOutput(_tCurrent, _h, _locStps);
    }

    #ifdef RUNTIME_PROFILING
    MEASURETIME_REGION_DEFINE(cvodeStepCompletedHandler, "CVodeStepCompleted");
    if(MeasureTime::getInstance() != NULL)
    {
        MEASURETIME_START(measuredFunctionStartValues, cvodeStepCompletedHandler, "CVodeStepCompleted");
    }
    #endif



    #ifdef RUNTIME_PROFILING
    if(MeasureTime::getInstance() != NULL)
    {
        MEASURETIME_END(measuredFunctionStartValues, measuredFunctionEndValues, (*measureTimeFunctionsArray)[5], cvodeStepCompletedHandler);
    }
    #endif

    // Perform state selection
    bool state_selection = stateSelection();
    if (state_selection)
      _continuous_system->getContinuousStates(_z);

    _zeroFound = false;

    // Check if step was successful
    if (check_flag(&_cv_rt, "CVode", 1))
    {
      _solverStatus = ISolver::SOLVERERROR;
      break;
    }

    // A root was found
    if ((_cv_rt == CV_ROOT_RETURN) && !isInterrupted())
    {
      // CVode is setting _tCurrent to the time where the first event occurred
      double _abs = fabs(_tLastEvent - _tCurrent);
      _zeroFound = true;

      if ((_abs < 1e-3) && _event_n == 0)
      {
        _tLastEvent = _tCurrent;
        _event_n++;
      }
      else if ((_abs < 1e-3) && (_event_n >= 1 && _event_n < 500))
      {
        _event_n++;
      }
      else if ((_abs >= 1e-3))
      {
        //restart event counter
        _tLastEvent = _tCurrent;
        _event_n = 0;
      }
      else
        throw ModelicaSimulationError(EVENT_HANDLING,"Number of events exceeded  in time interval " + to_string(_abs) + " at time " + to_string(_tCurrent));

      // CVode has interpolated the states at time 'tCurrent'
      _time_system->setTime(_tCurrent);

      // To get steep steps in the result file, two value points (P1 and P2) must be added
      //
      // Y |   (P2) X...........
      //   |        :
      //   |        :
      //   |........X (P1)
      //   |---------------------------------->
      //   |        ^                         t
      //        _tCurrent

      // Write the values of (P1)
      if (writeEventOutput)
      {
        _continuous_system->evaluateAll(IContinuous::CONTINUOUS);
        writeToFile(0, _tCurrent, _h);
      }

      _idid = CVodeGetRootInfo(_cvodeMem, _zeroSign);

      for (int i = 0; i < _dimZeroFunc; i++)
        _events[i] = bool(_zeroSign[i]);

      if (_mixed_system->handleSystemEvents(_events))
      {
        // State variables were reinitialized, thus we have to give these values to the cvode-solver
        // Take care about the memory regions, _z is the same like _CV_y
        _continuous_system->getContinuousStates(_z);
      }
    }

    if ((_zeroFound || state_selection)&& !isInterrupted())
    {
      // Write the values of (P2)
      if (writeEventOutput)
      {
        // If we want to write the event-results, we should evaluate the whole system again
        _continuous_system->evaluateAll(IContinuous::CONTINUOUS);
        writeToFile(0, _tCurrent, _h);
      }

      _idid = CVodeReInit(_cvodeMem, _tCurrent, _CV_y);
      if (_idid < 0)
        throw ModelicaSimulationError(SOLVER,"CVode::ReInit()");

      // Der Eventzeitpunkt kann auf der Endzeit liegen (Time-Events). In diesem Fall wird der Solver beendet, da CVode sonst eine interne Warnung schmeißt
      if (_tCurrent == _tEnd)
        _cv_rt = CV_TSTOP_RETURN;
      if(_continuous_system->stepCompleted(_tCurrent))
        _solverStatus = DONE;
    }

    // Zähler für die Anzahl der ausgegebenen Schritte erhöhen
    ++_outStps;
    _tLastSuccess = _tCurrent;

    if (_cv_rt == CV_TSTOP_RETURN)
    {
      _time_system->setTime(_tEnd);
      //Solver has finished calculation - calculate the final values
      _continuous_system->setContinuousStates(NV_DATA_S(_CV_y));
      _continuous_system->evaluateAll(IContinuous::CONTINUOUS);
      if(writeOutput)
         writeToFile(0, _tEnd, _h);

      _accStps += _locStps;
      _solverStatus = DONE;
    }
  }
}
Exemplo n.º 15
0
void FCV_REINIT(realtype *t0, realtype *y0, int *iatol, realtype *rtol,
                realtype *atol, int *optin, long int *iopt,
                realtype *ropt, int *ier)
{
  int itol;
  void *atolptr;

  atolptr = NULL;

  N_VSetArrayPointer(y0, F2C_vec);

  switch (*iatol) {
  case 1:
    itol = CV_SS; 
    atolptr = (void *) atol; 
    break;
  case 2:
    F2C_atolvec = N_VClone(F2C_vec);
    data_F2C_atolvec = N_VGetArrayPointer(F2C_atolvec);
    N_VSetArrayPointer(atol, F2C_atolvec);
    itol = CV_SV; 
    atolptr = (void *) F2C_atolvec; 
    break;
  case 3:
    itol = CV_WF;
  }

  /* 
     Call CVodeSet* and CVReInit to re-initialize CVODE: 
     CVf     is the user's right-hand side function in y'=f(t,y)
     t0      is the initial time
     F2C_vec is the initial dependent variable vector
     itol    specifies tolerance type
     rtol    is the scalar relative tolerance
     atolptr is the absolute tolerance pointer (to scalar or vector or function)
  */

  if (*optin == 1) {
    CV_optin = TRUE;
    if (iopt[0] > 0)     CVodeSetMaxOrd(CV_cvodemem, (int)iopt[0]);
    if (iopt[1] > 0)     CVodeSetMaxNumSteps(CV_cvodemem, iopt[1]);
    if (iopt[2] > 0)     CVodeSetMaxHnilWarns(CV_cvodemem, (int)iopt[2]);
    if (iopt[13] > 0)    CVodeSetStabLimDet(CV_cvodemem, TRUE);
    if (iopt[21] > 0)    CVodeSetMaxErrTestFails(CV_cvodemem, (int)iopt[21]);
    if (iopt[22] > 0)    CVodeSetMaxNonlinIters(CV_cvodemem, (int)iopt[22]);
    if (iopt[23] > 0)    CVodeSetMaxConvFails(CV_cvodemem, (int)iopt[23]);
    if (ropt[0] != ZERO) CVodeSetInitStep(CV_cvodemem, ropt[0]);
    if (ropt[1] > ZERO)  CVodeSetMaxStep(CV_cvodemem, ropt[1]);
    if (ropt[2] > ZERO)  CVodeSetMinStep(CV_cvodemem, ropt[2]);
    if (ropt[7] != ZERO) CVodeSetStopTime(CV_cvodemem, ropt[7]);
    if (ropt[8] > ZERO)  CVodeSetNonlinConvCoef(CV_cvodemem, ropt[8]);
  } else {
    CV_optin = FALSE;
  }

  *ier = CVodeReInit(CV_cvodemem, FCVf, *t0, F2C_vec, itol, *rtol, atolptr);

  /* reset data pointer into F2C_vec */
  N_VSetArrayPointer(data_F2C_vec, F2C_vec);

  /* destroy F2C_atolvec if allocated */
  if (F2C_atolvec != NULL) {
    N_VSetArrayPointer(data_F2C_atolvec, F2C_atolvec);
    N_VDestroy(F2C_atolvec);
  }

  if (*ier != CV_SUCCESS) {
    *ier = -1;
    return;
  }

  CV_iopt = iopt;
  CV_ropt = ropt;

  return;
}
Exemplo n.º 16
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;
}
Exemplo n.º 17
0
static int simulate_nmr_pulse(struct bloch_sim *bs)
{
    N_Vector M = NULL;
    M = N_VNew_Serial(3 * bs->num_cells);
    if (check_flag((void *)M, "N_VNew_Serial", 0)) return(1);

    int i;
    /* Set initial (t=0) magnetization conditions */
    for(i=0; i < bs->num_cells; ++i)
    {
        X(M,i) = 0.0;
        Y(M,i) = 0.0;
        Z(M,i) = bs->cell_frequencies[i] / bs->w_avg;
    }

    realtype reltol = RCONST(1.0e-14);
    realtype abstol = RCONST(1.0e-14);

    void *cvode_mem = CVodeCreate(CV_ADAMS, CV_FUNCTIONAL);
    if (check_flag((void *)cvode_mem, "CVodeCreate", 0)) return(1);

    int flag;
    //TODO: check if flag should be pointer;
    flag = CVodeInit(cvode_mem, bloch_equations, 0.0, M);
    if (check_flag(&flag, "CVodeInit", 1)) return(1);

    flag = CVodeSetUserData(cvode_mem, bs);
    if (check_flag(&flag, "CVodeSetUserData", 1)) return(1);

    flag = CVodeSStolerances(cvode_mem, reltol, abstol);
    if (check_flag(&flag, "CVodeSetUserData", 1)) return(1);

    flag = CVDense(cvode_mem, 3 * bs->num_cells);
    if (check_flag(&flag, "CVDense", 1)) return(1);

    flag = CVDlsSetDenseJacFn(cvode_mem, bloch_jacobian);
    if (check_flag(&flag, "CVDlsSetDenseJacFn", 1)) return(1);

    ///////////////////////////
    // PI/2 PULSE SIMULATION //
    ///////////////////////////
    bs->rf_on = 1;

    flag = CVodeSetStopTime(cvode_mem, bs->pi2_duration);
    if (check_flag(&flag, "CVodeSetStopTime", 1)) return 1;

    realtype time_reached;
    flag = CVode(cvode_mem, bs->pi2_duration, M, &time_reached, CV_NORMAL);

    if (flag != CV_SUCCESS)
    {
        printf("ERROR: Failed to simulate Pi/2 pulse\n");
    }

    // {{{ PI2 PULSE DEBUG STATEMENTS
    if (DEBUG)
    {
        printf("\n");
        printf("#####################################\n");
        printf("### PI/2 PULSE SIMULATION DETAILS ###\n");
        printf("#####################################\n");
        printf("\n");

        printf("TIME REACHED: %.15e\n", time_reached);
        printf("TIME REACHED - PI2_DURATION: %.15e\n", time_reached - bs->pi2_duration);

        printf("\n");
        printf("MAGNETIZATION AT END OF PI/2 PULSE:\n");
        for (i = 0; i<bs->num_cells; ++i)
        {
            printf("CELL %d: %.4e, %.4e, %.4e\n", i, X(M,i), Y(M,i), Z(M,i));
        }
    }
    // }}}

    ////////////////////
    // FID SIMULATION //
    ////////////////////
    bs->rf_on = 0;

    if (DEBUG)
    {
        printf("##############################\n");
        printf("### FID SIMULATION DETAILS ###\n");
        printf("##############################\n");
    }

    flag = CVodeReInit(cvode_mem, 0.0, M);
    if (check_flag(&flag, "CVodeReInit", 1)) return(1);
    time_reached = 0.0;

    flag = CVodeSetStopTime(cvode_mem, bs->fid_duration);
    if (check_flag(&flag, "CVodeSetStopTime", 1)) return 1;

    flag = CVodeRootInit(cvode_mem, 1, bloch_root);
    if (check_flag(&flag, "CVodeRootInit", 1)) return 1;

    realtype time_desired, M_FID_X;
    while (time_reached < bs->fid_duration)
    {
        time_desired = time_reached + bs->fid_sampling_interval;
        flag = CVode(cvode_mem, time_desired, M, &time_reached, CV_NORMAL);

        if (flag == CV_ROOT_RETURN)
        {
            bs->zero_crossings[bs->num_zero_crossings] = time_reached;

            M_FID_X = 0.0;
            for (i=0; i < bs->num_cells; i++)
            {
                M_FID_X += X(M,i) * cos(bs->w_avg * time_reached);
                M_FID_X += Y(M,i) * sin(bs->w_avg * time_reached);
            }
            bs->envelope[bs->num_zero_crossings] = M_FID_X / bs->num_cells;
            bs->num_zero_crossings++;
        }
    }

    bs->zero_crossings = (realtype*) realloc(bs->zero_crossings, sizeof(realtype) * bs->num_zero_crossings);
    bs->envelope = (realtype*) realloc(bs->envelope, sizeof(realtype) * bs->num_zero_crossings);
    if (!bs->zero_crossings || !bs->envelope) {
        printf("ERROR: reallocating zero crossing and/or envelope array memory failed!\n");
        exit(1);
    }

    N_VDestroy_Serial(M);

    CVodeFree(&cvode_mem);

    return 0;
}
Exemplo n.º 18
0
int main(void)
{
  realtype abstol, reltol, t, tout;
  N_Vector u;
  UserData data;
  void *cvode_mem;
  int linsolver, iout, flag;

  u = NULL;
  data = NULL;
  cvode_mem = NULL;

  /* Allocate memory, and set problem data, initial values, tolerances */ 
  u = N_VNew_Serial(NEQ);
  if(check_flag((void *)u, "N_VNew_Serial", 0)) return(1);
  data = AllocUserData();
  if(check_flag((void *)data, "AllocUserData", 2)) return(1);
  InitUserData(data);
  SetInitialProfiles(u, data->dx, data->dy);
  abstol=ATOL; 
  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);

  /* Set the pointer to user-defined data */
  flag = CVodeSetUserData(cvode_mem, data);
  if(check_flag(&flag, "CVodeSetUserData", 1)) return(1);

  /* Call CVodeInit to initialize the integrator memory and specify the
   * user's right hand side function in u'=f(t,u), the inital time T0, and
   * the initial dependent variable vector u. */
  flag = CVodeInit(cvode_mem, f, T0, u);
  if(check_flag(&flag, "CVodeInit", 1)) return(1);

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

  /* START: Loop through SPGMR, SPBCG and SPTFQMR linear solver modules */
  for (linsolver = 0; linsolver < 3; ++linsolver) {

    if (linsolver != 0) {

      /* Re-initialize user data */
      InitUserData(data);
      SetInitialProfiles(u, data->dx, data->dy);

    /* Re-initialize CVode for the solution of the same problem, but
       using a different linear solver module */
      flag = CVodeReInit(cvode_mem, T0, u);
      if (check_flag(&flag, "CVodeReInit", 1)) return(1);

    }

    /* Attach a linear solver module */
    switch(linsolver) {

    /* (a) SPGMR */
    case(USE_SPGMR):

      /* Print header */
      printf(" -------");
      printf(" \n| SPGMR |\n");
      printf(" -------\n");

      /* Call CVSpgmr to specify the linear solver CVSPGMR 
	 with left preconditioning and the maximum Krylov dimension maxl */
      flag = CVSpgmr(cvode_mem, PREC_LEFT, 0);
      if(check_flag(&flag, "CVSpgmr", 1)) return(1);

      /* Set modified Gram-Schmidt orthogonalization, preconditioner 
	 setup and solve routines Precond and PSolve, and the pointer 
	 to the user-defined block data */
      flag = CVSpilsSetGSType(cvode_mem, MODIFIED_GS);
      if(check_flag(&flag, "CVSpilsSetGSType", 1)) return(1);

      break;

    /* (b) SPBCG */
    case(USE_SPBCG):

      /* Print header */
      printf(" -------");
      printf(" \n| SPBCG |\n");
      printf(" -------\n");

      /* Call CVSpbcg to specify the linear solver CVSPBCG 
	 with left preconditioning and the maximum Krylov dimension maxl */
      flag = CVSpbcg(cvode_mem, PREC_LEFT, 0);
      if(check_flag(&flag, "CVSpbcg", 1)) return(1);

      break;

    /* (c) SPTFQMR */
    case(USE_SPTFQMR):

      /* Print header */
      printf(" ---------");
      printf(" \n| SPTFQMR |\n");
      printf(" ---------\n");

      /* Call CVSptfqmr to specify the linear solver CVSPTFQMR 
	 with left preconditioning and the maximum Krylov dimension maxl */
      flag = CVSptfqmr(cvode_mem, PREC_LEFT, 0);
      if(check_flag(&flag, "CVSptfqmr", 1)) return(1);

      break;

    }


    /* Set preconditioner setup and solve routines Precond and PSolve,
       and the pointer to the user-defined block data */
    flag = CVSpilsSetPreconditioner(cvode_mem, Precond, PSolve);
    if(check_flag(&flag, "CVSpilsSetPreconditioner", 1)) return(1);

    /* In loop over output points, call CVode, print results, test for error */
    printf(" \n2-species diurnal advection-diffusion problem\n\n");
    for (iout=1, tout = TWOHR; iout <= NOUT; iout++, tout += TWOHR) {
      flag = CVode(cvode_mem, tout, u, &t, CV_NORMAL);
      PrintOutput(cvode_mem, u, t);
      if(check_flag(&flag, "CVode", 1)) break;
    }

    PrintFinalStats(cvode_mem, linsolver);

  }  /* END: Loop through SPGMR, SPBCG and SPTFQMR linear solver modules */

  /* Free memory */
  N_VDestroy_Serial(u);
  FreeUserData(data);
  CVodeFree(&cvode_mem);

  return(0);
}
Exemplo n.º 19
0
	void OpenSMOKE_CVODE_Sundials<T>::Solve(const double xend)
	{

		int flag;

		this->x_ = this->x0_;
		this->xend_ = xend;

		for(int i=0;i<this->n_;i++)
			NV_Ith_S(y0Sundials_,i) = this->y0_[i];

		if (firstCall_ == true)
		{
			firstCall_ = false;

			/* 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_, std::string("CVodeCreate"), 0)) exit(-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 y0Sundials_. */
			flag = CVodeInit(cvode_mem_, this->odeSystem_->GetSystemFunctionsStatic, this->odeSystem_->GetWriteFunctionStatic, this->x0_, y0Sundials_);
			if (check_flag(&flag, std::string("CVodeInit"), 1)) exit(-1);

			/* Call CVodeSVtolerances to specify the scalar relative tolerance
			* and vector absolute tolerances */
			flag = CVodeSStolerances(cvode_mem_, this->relTolerance_[0], this->absTolerance_[0]);
			if (check_flag(&flag, std::string("CVodeSVtolerances"), 1)) exit(-1);

			/* Call Solver */
			if (this->iUseLapack_ == false)
			{
				if (this->mUpper_ == 0 && this->mLower_ == 0)
				{
//					std::cout << "CVODE Solver: Dense Jacobian (without Lapack)..." << std::endl;
					flag = CVDense(cvode_mem_, this->n_);
					if (check_flag(&flag, std::string("CVDense"), 1)) exit(-1);
				}
				else
				{
//					std::cout << "CVODE Solver: Band Jacobian (without Lapack)..." << std::endl;
					flag = CVBand(cvode_mem_, this->n_, this->mUpper_, this->mLower_);
					if (check_flag(&flag, std::string("CVBand"), 1)) exit(-1);
				}
			}
			else
			{
				if (this->mUpper_ == 0 && this->mLower_ == 0)
				{
//					std::cout << "CVODE Solver: Dense Jacobian (with Lapack)..." << std::endl;
					flag = CVLapackDense(cvode_mem_, this->n_);
					if (check_flag(&flag, std::string("CVLapackDense"), 1)) exit(-1);
				}
				else
				{
//					std::cout << "CVODE Solver: Band Jacobian (with Lapack)..." << std::endl;
					flag = CVLapackBand(cvode_mem_, this->n_, this->mUpper_, this->mLower_);
					if (check_flag(&flag, std::string("CVLapackBand"), 1)) exit(-1);
				}
			}
		}
		else
		{
			flag = CVodeReInit(cvode_mem_, this->x0_, y0Sundials_);
			if (check_flag(&flag, std::string("CVodeReInit"), 1)) exit(-1);
		}

		AnalyzeUserOptions();

		/* Solving */
		this->tStart_ =  this->GetClockTime();
		flag = CVode(cvode_mem_, this->xend_, ySundials_, &this->x_, CV_NORMAL);
		this->tEnd_ =  this->GetClockTime();

		this->x0_ = this->x_;
		for(int i=0;i<this->n_;i++)
			NV_Ith_S(y0Sundials_,i) = NV_Ith_S(ySundials_,i);
		for(int i=0;i<this->n_;i++)
			this->y_[i] = NV_Ith_S(ySundials_,i);
	}
Exemplo n.º 20
0
static int CVAckpntGet(CVodeMem cv_mem, CkpntMem ck_mem) 
{
  int j;
  int flag;
  int qmax;
  void *abstol;

  abstol = NULL;

  if (next_ == NULL) {

    /* In this case, we just call the reinitialization routine,
       but make sure we use the same initial stepsize as on 
       the first run. */

    CVodeSetInitStep(cv_mem, h0u);

    switch (itol) {
    case CV_SS:
      abstol = (void *) &Sabstol;
      break;
    case CV_SV:
      abstol = (void *)Vabstol;
      break;
    case CV_EE:
      abstol = (void *)efun;
      break;
    }
    flag = CVodeReInit(cv_mem, f, t0_, zn_[0], itol, reltol, abstol);
    if (flag != CV_SUCCESS) return(flag);

    if(quadr_) {
      flag = CVodeQuadReInit(cv_mem, fQ, znQ_[0]);
      if (flag != CV_SUCCESS) return(flag);
    }

  } else {
    
    qmax = cv_mem->cv_qmax;

    /* Copy parameters from check point data structure */
    nst       = nst_;
    tretlast  = tretlast_;
    q         = q_;
    qprime    = qprime_;
    qwait     = qwait_;
    L         = L_;
    gammap    = gammap_;
    h         = h_;
    hprime    = hprime_;
    hscale    = hscale_;
    eta       = eta_;
    etamax    = etamax_;
    tn        = t0_;
    saved_tq5 = saved_tq5_;
    
    /* Copy the arrays from check point data structure */
    for (j=0; j<=q; j++) N_VScale(ONE, zn_[j], zn[j]);
    if ( q < qmax ) N_VScale(ONE, zn_[qmax], zn[qmax]);
    if(quadr_) {
      for (j=0; j<=q; j++) N_VScale(ONE, znQ_[j], znQ[j]);
      if ( q < qmax ) N_VScale(ONE, znQ_[qmax], znQ[qmax]);
    }
    for (j=0; j<=L_MAX; j++)     tau[j] = tau_[j];
    for (j=0; j<=NUM_TESTS; j++) tq[j] = tq_[j];
    for (j=0; j<=q; j++)         l[j] = l_[j];
    
    /* Force a call to setup */
    forceSetup = TRUE;

  }

  return(CV_SUCCESS);
}
Exemplo n.º 21
0
int jmi_ode_cvode_solve(jmi_ode_solver_t* solver, realtype time_final, int initialize){
    int flag = 0,retval = 0;
    jmi_ode_cvode_t* integrator = (jmi_ode_cvode_t*)solver->integrator;
    jmi_ode_problem_t* problem = solver -> ode_problem;
    realtype tret/*,*y*/;
    realtype time;
    char step_event = 0; /* boolean step_event = FALSE */
    
    if (initialize==JMI_TRUE){
        /* statements unused*/
        /*
        if (problem->n_real_x > 0) {
            y = NV_DATA_S(integrator->y_work);
            y = problem->states;
        }
        */
		memcpy (NV_DATA_S(integrator->y_work), problem->states, problem->n_real_x*sizeof(jmi_real_t));
        time = problem->time;
        flag = CVodeReInit(integrator->cvode_mem, time, integrator->y_work);
        if (flag<0){
            jmi_log_node(problem->log, logError, "Error", "Failed to re-initialize the solver. "
                         "Returned with <error_flag: %d>", flag);
            return JMI_ODE_ERROR;
        }
    }
    
    /* Dont integrate past t_stop */
    flag = CVodeSetStopTime(integrator->cvode_mem, time_final);
    if (flag < 0){
        jmi_log_node(problem->log, logError, "Error", "Failed to specify the stop time. "
                     "Returned with <error_flag: %d>", flag);
        return JMI_ODE_ERROR;
    }
    
    /*
    flag = CVode(integrator->cvode_mem, time_final, integrator->y_work, &tret, CV_NORMAL);
    if(flag<0){
        jmi_log_node(problem->log, logError, "Error", "Failed to calculate the next step. "
                     "Returned with <error_flag: %d>", flag);
        return JMI_ODE_ERROR;
    }
    */
    
    flag = CV_SUCCESS;
    while (flag == CV_SUCCESS) {
        
        /* Perform a step */
        flag = CVode(integrator->cvode_mem, time_final, integrator->y_work, &tret, CV_ONE_STEP);
        if(flag<0){
            jmi_log_node(problem->log, logError, "Error", "Failed to calculate the next step. "
                     "Returned with <error_flag: %d>", flag);
            return JMI_ODE_ERROR;
        }
        
        /* After each step call completed integrator step */
        retval = problem->complete_step_func(problem, &step_event);
        if (retval != 0) {
            jmi_log_node(problem->log, logError, "Error", "Failed to complete an integrator step. "
                     "Returned with <error_flag: %d>", retval);
            return JMI_ODE_ERROR;
        }
        
        if (step_event == TRUE) {
            jmi_log_node(problem->log, logInfo, "STEPEvent", "An event was detected at <t:%g>", tret);
            return JMI_ODE_EVENT;
        }
        
    }
    
    /*
    time = problem->time;
    if (time != tret) {
        flag = problem->rhs_func(problem, tret, NV_DATA_S(integrator->y_work), problem->states_derivative);
        if(flag != 0) {
            jmi_log_node(problem->log, logWarning, "Warning", "Evaluating the derivatives failed (recoverable error). "
                     "Returned with <warningFlag: %d>", flag);
            return JMI_ODE_ERROR;
        }
        printf("Difference at time %g\n",tret);
    }
    */
    
    if (flag == CV_ROOT_RETURN){
        jmi_log_node(problem->log, logInfo, "CVODEEvent", "An event was detected at <t:%g>", tret);
        return JMI_ODE_EVENT;
    }
    return JMI_ODE_OK;
}
Exemplo n.º 22
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);
}
Exemplo n.º 23
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);
}
Exemplo n.º 24
0
static int Problem2(void)
{
  realtype reltol=RTOL, abstol=ATOL, t, tout, er, erm, ero;
  int miter, flag, temp_flag, nerr=0;
  N_Vector y;
  void *cvode_mem;
  booleantype firstrun;
  int qu, iout;
  realtype hu;

  y = NULL;
  cvode_mem = NULL;

  y = N_VNew_Serial(P2_NEQ);
  if(check_flag((void *)y, "N_VNew", 0)) return(1);

  PrintIntro2();

  cvode_mem = CVodeCreate(CV_ADAMS, CV_FUNCTIONAL);
  if(check_flag((void *)cvode_mem, "CVodeCreate", 0)) return(1);

  for (miter=FUNC; miter <= BAND_DQ; miter++) {
    if ((miter==DENSE_USER) || (miter==DENSE_DQ)) continue;
    ero = ZERO;
    N_VConst(ZERO, y);
    NV_Ith_S(y,0) = ONE;
      
    firstrun = (miter==FUNC);
    if (firstrun) {
      flag = CVodeMalloc(cvode_mem, f2, P2_T0, y, CV_SS, reltol, &abstol);
      if(check_flag(&flag, "CVodeMalloc", 1)) return(1);
    } else {
      flag = CVodeSetIterType(cvode_mem, CV_NEWTON);
      if(check_flag(&flag, "CVodeSetIterType", 1)) ++nerr;
      flag = CVodeReInit(cvode_mem, f2, P2_T0, y, CV_SS, reltol, &abstol);
      if(check_flag(&flag, "CVodeReInit", 1)) return(1);
    }
      
    flag = PrepareNextRun(cvode_mem, CV_ADAMS, miter, P2_MU, P2_ML);
    if(check_flag(&flag, "PrepareNextRun", 1)) return(1);

    PrintHeader2();

    for(iout=1, tout=P2_T1; iout <= P2_NOUT; iout++, tout*=P2_TOUT_MULT) {
      flag = CVode(cvode_mem, tout, y, &t, CV_NORMAL);
      check_flag(&flag, "CVode", 1);
      erm = MaxError(y, t);
      temp_flag = CVodeGetLastOrder(cvode_mem, &qu);
      if(check_flag(&temp_flag, "CVodeGetLastOrder", 1)) ++nerr;
      temp_flag = CVodeGetLastStep(cvode_mem, &hu);
      if(check_flag(&temp_flag, "CVodeGetLastStep", 1)) ++nerr;
      PrintOutput2(t, erm, qu, hu);
      if (flag != CV_SUCCESS) {
        nerr++;
        break;
      }
      er = erm / abstol;
        if (er > ero) ero = er;
        if (er > P2_TOL_FACTOR) {
          nerr++;
          PrintErrOutput(P2_TOL_FACTOR);
        }
    }
    
    PrintFinalStats(cvode_mem, miter, ero);
  }

  CVodeFree(cvode_mem);

  cvode_mem = CVodeCreate(CV_BDF, CV_FUNCTIONAL);
  if(check_flag((void *)cvode_mem, "CVodeCreate", 0)) return(1);

  for (miter=FUNC; miter <= BAND_DQ; miter++) {
    if ((miter==DENSE_USER) || (miter==DENSE_DQ)) continue;
    ero = ZERO;
    N_VConst(ZERO, y);
    NV_Ith_S(y,0) = ONE;
      
    firstrun = (miter==FUNC);
    if (firstrun) {
      flag = CVodeMalloc(cvode_mem, f2, P2_T0, y, CV_SS, reltol, &abstol);
      if(check_flag(&flag, "CVodeMalloc", 1)) return(1);
    } else {
      flag = CVodeSetIterType(cvode_mem, CV_NEWTON);
      if(check_flag(&flag, "CVodeSetIterType", 1)) ++nerr;
      flag = CVodeReInit(cvode_mem, f2, P2_T0, y, CV_SS, reltol, &abstol);
      if(check_flag(&flag, "CVodeReInit", 1)) return(1);
    }

    flag = PrepareNextRun(cvode_mem, CV_BDF, miter, P2_MU, P2_ML);
    if(check_flag(&flag, "PrepareNextRun", 1)) return(1);

    PrintHeader2();
      
    for(iout=1, tout=P2_T1; iout <= P2_NOUT; iout++, tout*=P2_TOUT_MULT) {
      flag = CVode(cvode_mem, tout, y, &t, CV_NORMAL);
      check_flag(&flag, "CVode", 1);
      erm = MaxError(y, t);
      temp_flag = CVodeGetLastOrder(cvode_mem, &qu);
      if(check_flag(&temp_flag, "CVodeGetLastOrder", 1)) ++nerr;
      temp_flag = CVodeGetLastStep(cvode_mem, &hu);
      if(check_flag(&temp_flag, "CVodeGetLastStep", 1)) ++nerr;
      PrintOutput2(t, erm, qu, hu);
      if (flag != CV_SUCCESS) {
        nerr++;
        break;
      }
      er = erm / abstol;
        if (er > ero) ero = er;
        if (er > P2_TOL_FACTOR) {
          nerr++;
          PrintErrOutput(P2_TOL_FACTOR);
        }
    }
    
    PrintFinalStats(cvode_mem, miter, ero);
  }

  CVodeFree(cvode_mem);
  N_VDestroy_Serial(y);

  return(nerr);
}
	void OpenSMOKE_CVODE_Sundials<T>::Solve(const double xend)
	{

		int flag;

		this->x_ = this->x0_;
		this->xend_ = xend;

		for(int i=0;i<this->n_;i++)
			NV_Ith_S(y0Sundials_,i) = this->y0_[i];

		if (firstCall_ == true)
		{
			firstCall_ = false;

			/* 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_, std::string("CVodeCreate"), 0)) exit(-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 y0Sundials_. */
			flag = CVodeInit(cvode_mem_, this->odeSystem_->GetSystemFunctionsStatic, this->odeSystem_->GetWriteFunctionStatic, this->x0_, y0Sundials_);
			if (check_flag(&flag, std::string("CVodeInit"), 1)) exit(-1);

			/* Call CVodeSVtolerances to specify the scalar relative tolerance
			* and vector absolute tolerances */
			flag = CVodeSStolerances(cvode_mem_, this->relTolerance_[0], this->absTolerance_[0]);
			if (check_flag(&flag, std::string("CVodeSVtolerances"), 1)) exit(-1);

			/* Call Solver */
			if (this->iUseLapack_ == false)
			{
				if (this->mUpper_ == 0 && this->mLower_ == 0)
				{
					// std::cout << "CVODE Solver: Dense Jacobian (without Lapack)..." << std::endl;

					/* Create dense SUNMatrix for use in linear solves */
					A = SUNDenseMatrix(this->n_, this->n_);
					if (check_flag((void *)A, std::string("SUNDenseMatrix"), 0)) exit(-1);
					
					/* Create SUNDenseLinearSolver solver object for use by CVode */
					LS = SUNDenseLinearSolver(ySundials_, A);
					if (check_flag((void *)LS, std::string("SUNDenseLinearSolver"), 0)) exit(-1);
				}
				else
				{
					// std::cout << "CVODE Solver: Band Jacobian (without Lapack)..." << std::endl;

					/* Create banded SUNMatrix for use in linear solves -- since this will be factored,
					set the storage bandwidth to be the sum of upper and lower bandwidths */
					A = SUNBandMatrix(this->n_, this->mUpper_, this->mLower_, (this->mUpper_+this->mLower_) );
					if (check_flag((void *)A, std::string("SUNBandMatrix"), 0)) exit(-1);

					/* Create banded SUNLinearSolver object for use by CVode */
					LS = SUNBandLinearSolver(ySundials_, A);
					if (check_flag((void *)LS, std::string("SUNBandLinearSolver"), 0)) exit(-1);
				}
			}
			else
			{
				if (this->mUpper_ == 0 && this->mLower_ == 0)
				{
					// std::cout << "CVODE Solver: Dense Jacobian (with Lapack)..." << std::endl;

					/* Create dense SUNMatrix for use in linear solves */
					A = SUNDenseMatrix(this->n_, this->n_);
					if (check_flag((void *)A, std::string("SUNDenseMatrix"), 0)) exit(-1);

					/* Create SUNLapackDense solver object for use by CVode */
					LS = SUNLapackDense(ySundials_, A);
					if (check_flag((void *)LS, std::string("SUNLapackDense"), 0)) exit(-1);
				}
				else
				{
					// std::cout << "CVODE Solver: Band Jacobian (with Lapack)..." << std::endl;

					/* Create banded SUNMatrix for use in linear solves -- since this will be factored,
					set the storage bandwidth to be the sum of upper and lower bandwidths */
					A = SUNBandMatrix(this->n_, this->mUpper_, this->mLower_, (this->mUpper_ + this->mLower_));
					if (check_flag((void *)A, std::string("SUNBandMatrix"), 0)) exit(-1);

					/* Create banded SUNLapackBand solver object for use by CVode */
					LS = SUNLapackBand(ySundials_, A);
					if (check_flag((void *)LS, std::string("SUNLapackBand"), 0)) exit(-1);
				}
			}

			/* Call CVDlsSetLinearSolver to attach the matrix and linear solver to CVode */
			flag = CVDlsSetLinearSolver(cvode_mem_, LS, A);
			if (check_flag(&flag, std::string("CVDlsSetLinearSolver"), 1)) exit(-1);
		}
		else
		{
			flag = CVodeReInit(cvode_mem_, this->x0_, y0Sundials_);
			if (check_flag(&flag, std::string("CVodeReInit"), 1)) exit(-1);
		}

		AnalyzeUserOptions();

		/* Solving */
		this->tStart_ =  this->GetClockTime();
		flag = CVode(cvode_mem_, this->xend_, ySundials_, &this->x_, CV_NORMAL);
		this->tEnd_ =  this->GetClockTime();

		this->x0_ = this->x_;
		for(int i=0;i<this->n_;i++)
			NV_Ith_S(y0Sundials_,i) = NV_Ith_S(ySundials_,i);
		for(int i=0;i<this->n_;i++)
			this->y_[i] = NV_Ith_S(ySundials_,i);
	}
int main()
{
    realtype abstol=ATOL, reltol=RTOL, t, tout;
    N_Vector c;
    WebData wdata;
    void *cvode_mem;
    booleantype firstrun;
    int jpre, gstype, flag;
    int ns, mxns, iout;

    c = NULL;
    wdata = NULL;
    cvode_mem = NULL;

    /* Initializations */
    c = N_VNew_Serial(NEQ);
    if(check_flag((void *)c, "N_VNew_Serial", 0)) return(1);
    wdata = AllocUserData();
    if(check_flag((void *)wdata, "AllocUserData", 2)) return(1);
    InitUserData(wdata);
    ns = wdata->ns;
    mxns = wdata->mxns;

    /* Print problem description */
    PrintIntro();

    /* Loop over jpre and gstype (four cases) */
    for (jpre = PREC_LEFT; jpre <= PREC_RIGHT; jpre++) {
        for (gstype = MODIFIED_GS; gstype <= CLASSICAL_GS; gstype++) {

            /* Initialize c and print heading */
            CInit(c, wdata);
            PrintHeader(jpre, gstype);

            /* Call CVodeInit or CVodeReInit, then CVSpgmr to set up problem */

            firstrun = (jpre == PREC_LEFT) && (gstype == MODIFIED_GS);
            if (firstrun) {
                cvode_mem = CVodeCreate(CV_BDF, CV_NEWTON);
                if(check_flag((void *)cvode_mem, "CVodeCreate", 0)) return(1);

                wdata->cvode_mem = cvode_mem;

                flag = CVodeSetUserData(cvode_mem, wdata);
                if(check_flag(&flag, "CVodeSetUserData", 1)) return(1);

                flag = CVodeInit(cvode_mem, f, T0, c);
                if(check_flag(&flag, "CVodeInit", 1)) return(1);

                flag = CVodeSStolerances(cvode_mem, reltol, abstol);
                if (check_flag(&flag, "CVodeSStolerances", 1)) return(1);

                flag = CVSpgmr(cvode_mem, jpre, MAXL);
                if(check_flag(&flag, "CVSpgmr", 1)) return(1);

                flag = CVSpilsSetGSType(cvode_mem, gstype);
                if(check_flag(&flag, "CVSpilsSetGSType", 1)) return(1);

                flag = CVSpilsSetEpsLin(cvode_mem, DELT);
                if(check_flag(&flag, "CVSpilsSetEpsLin", 1)) return(1);

                flag = CVSpilsSetPreconditioner(cvode_mem, Precond, PSolve);
                if(check_flag(&flag, "CVSpilsSetPreconditioner", 1)) return(1);

            } else {

                flag = CVodeReInit(cvode_mem, T0, c);
                if(check_flag(&flag, "CVodeReInit", 1)) return(1);

                flag = CVSpilsSetPrecType(cvode_mem, jpre);
                check_flag(&flag, "CVSpilsSetPrecType", 1);
                flag = CVSpilsSetGSType(cvode_mem, gstype);
                if(check_flag(&flag, "CVSpilsSetGSType", 1)) return(1);

            }

            /* Print initial values */
            if (firstrun) PrintAllSpecies(c, ns, mxns, T0);

            /* Loop over output points, call CVode, print sample solution values. */
            tout = T1;
            for (iout = 1; iout <= NOUT; iout++) {
                flag = CVode(cvode_mem, tout, c, &t, CV_NORMAL);
                PrintOutput(cvode_mem, t);
                if (firstrun && (iout % 3 == 0)) PrintAllSpecies(c, ns, mxns, t);
                if(check_flag(&flag, "CVode", 1)) break;
                if (tout > RCONST(0.9)) tout += DTOUT;
                else tout *= TOUT_MULT;
            }

            /* Print final statistics, and loop for next case */
            PrintFinalStats(cvode_mem);

        }
    }

    /* Free all memory */
    CVodeFree(&cvode_mem);
    N_VDestroy_Serial(c);
    FreeUserData(wdata);

    return(0);
}
Exemplo n.º 27
0
int main(int argc, char *argv[])
{
  UserData data;
  void *cvode_mem;
  realtype abstol, reltol, t, tout;
  N_Vector u;
  int iout, my_pe, npes, flag, jpre;
  long int neq, local_N, mudq, mldq, mukeep, mlkeep;
  MPI_Comm comm;

  data = NULL;
  cvode_mem = NULL;
  u = NULL;

  /* Set problem size neq */
  neq = NVARS*MX*MY;

  /* Get processor number and total number of pe's */
  MPI_Init(&argc, &argv);
  comm = MPI_COMM_WORLD;
  MPI_Comm_size(comm, &npes);
  MPI_Comm_rank(comm, &my_pe);

  if (npes != NPEX*NPEY) {
    if (my_pe == 0)
      fprintf(stderr, "\nMPI_ERROR(0): npes = %d is not equal to NPEX*NPEY = %d\n\n",
              npes, NPEX*NPEY);
    MPI_Finalize();
    return(1);
  }

  /* Set local length */
  local_N = NVARS*MXSUB*MYSUB;

  /* Allocate and load user data block */
  data = (UserData) malloc(sizeof *data);
  if(check_flag((void *)data, "malloc", 2, my_pe)) MPI_Abort(comm, 1);
  InitUserData(my_pe, local_N, comm, data);

  /* Allocate and initialize u, and set tolerances */ 
  u = N_VNew_Parallel(comm, local_N, neq);
  if(check_flag((void *)u, "N_VNew_Parallel", 0, my_pe)) MPI_Abort(comm, 1);
  SetInitialProfiles(u, data);
  abstol = ATOL;
  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, my_pe)) MPI_Abort(comm, 1);

  /* Set the pointer to user-defined data */
  flag = CVodeSetUserData(cvode_mem, data);
  if(check_flag(&flag, "CVodeSetUserData", 1, my_pe)) MPI_Abort(comm, 1);

  /* Call CVodeInit to initialize the integrator memory and specify the
   * user's right hand side function in u'=f(t,u), the inital time T0, and
   * the initial dependent variable vector u. */
  flag = CVodeInit(cvode_mem, f, T0, u);
  if(check_flag(&flag, "CVodeInit", 1, my_pe)) return(1);

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

  /* Call CVSpgmr to specify the linear solver CVSPGMR with left
     preconditioning and the default maximum Krylov dimension maxl  */
  flag = CVSpgmr(cvode_mem, PREC_LEFT, 0);
  if(check_flag(&flag, "CVBBDSpgmr", 1, my_pe)) MPI_Abort(comm, 1);

  /* Initialize BBD preconditioner */
  mudq = mldq = NVARS*MXSUB;
  mukeep = mlkeep = NVARS;
  flag = CVBBDPrecInit(cvode_mem, local_N, mudq, mldq, 
                       mukeep, mlkeep, ZERO, flocal, NULL);
  if(check_flag(&flag, "CVBBDPrecAlloc", 1, my_pe)) MPI_Abort(comm, 1);

  /* Print heading */
  if (my_pe == 0) PrintIntro(npes, mudq, mldq, mukeep, mlkeep);

  /* Loop over jpre (= PREC_LEFT, PREC_RIGHT), and solve the problem */
  for (jpre = PREC_LEFT; jpre <= PREC_RIGHT; jpre++) {

  /* On second run, re-initialize u, the integrator, CVBBDPRE, and CVSPGMR */

  if (jpre == PREC_RIGHT) {

    SetInitialProfiles(u, data);

    flag = CVodeReInit(cvode_mem, T0, u);
    if(check_flag(&flag, "CVodeReInit", 1, my_pe)) MPI_Abort(comm, 1);

    flag = CVBBDPrecReInit(cvode_mem, mudq, mldq, ZERO);
    if(check_flag(&flag, "CVBBDPrecReInit", 1, my_pe)) MPI_Abort(comm, 1);

    flag = CVSpilsSetPrecType(cvode_mem, PREC_RIGHT);
    check_flag(&flag, "CVSpilsSetPrecType", 1, my_pe);

    if (my_pe == 0) {
      printf("\n\n-------------------------------------------------------");
      printf("------------\n");
    }

  }


  if (my_pe == 0) {
    printf("\n\nPreconditioner type is:  jpre = %s\n\n",
	   (jpre == PREC_LEFT) ? "PREC_LEFT" : "PREC_RIGHT");
  }

  /* In loop over output points, call CVode, print results, test for error */

  for (iout = 1, tout = TWOHR; iout <= NOUT; iout++, tout += TWOHR) {
    flag = CVode(cvode_mem, tout, u, &t, CV_NORMAL);
    if(check_flag(&flag, "CVode", 1, my_pe)) break;
    PrintOutput(cvode_mem, my_pe, comm, u, t);
  }

  /* Print final statistics */

  if (my_pe == 0) PrintFinalStats(cvode_mem);

  } /* End of jpre loop */

  /* Free memory */
  N_VDestroy_Parallel(u);
  free(data);
  CVodeFree(&cvode_mem);

  MPI_Finalize();

  return(0);
}
Exemplo n.º 28
0
void Bloch_McConnell_CV_Model::InitSolver    () {

	m_world     = World::instance();
	
	m_ncomp     = m_world->GetNoOfCompartments();
	m_nprops    = m_world->GetNoOfSpinProps();
	int m_ncoprops = (m_nprops - 4) / m_ncomp;
	
	double* m0s = new double[m_ncomp];
	int     n   = 0;
	
	for (int i = 0; i < m_ncomp; i++) {

		m0s[i] = m_world->Values[m_ncoprops*i+M0];
		if (m0s[i] > 0.0)
			n++;
	}

	m_bmaux.Init(m_ncomp); 
	
	if (n == 1)
		m_bmaux.single  = true;


	//Compute local exchange rates and return them in member matrix
	LocalExchangeRates (m_world->Helper(), m_bmaux.exrates, m0s, m_ncomp);

	delete [] m0s;
	
	m_world->auxiliary = (void*) (&m_bmaux);
	
    ((bmnvec*) (m_world->solverSettings))->y = N_VNew_Serial(NEQ*m_ncomp);
	
    // loop over pools, stepsize NEQ
    for ( int i = 0; i < m_ncomp*NEQ; i += NEQ ){

    	NV_Ith_S( ((bmnvec*) (m_world->solverSettings))->y,XC+i )  = m_world->solution[AMPL+i]*cos(m_world->solution[PHASE+i]);// polar coordinates
    	NV_Ith_S( ((bmnvec*) (m_world->solverSettings))->y,YC+i )  = m_world->solution[AMPL+i]*sin(m_world->solution[PHASE+i]);
    	NV_Ith_S( ((bmnvec*) (m_world->solverSettings))->y,ZC+i )  = m_world->solution[ZC+i];

    }
	
    ((bmnvec*) (m_world->solverSettings))->abstol = N_VNew_Serial(NEQ*m_ncomp);
	
    // loop over pools, stepsize NEQ
    int poolVal = 0;
    for ( int i = 0; i< m_ncomp*NEQ; i+=NEQ ){

    	if (fabs(m_world->Values[m_ncoprops*poolVal+M0])<BEPS){

    		NV_Ith_S( ((bmnvec*) (m_world->solverSettings))->abstol,XC+i )  = ATOL1;
			NV_Ith_S( ((bmnvec*) (m_world->solverSettings))->abstol,ZC+i )  = ATOL3;

    	} else{

	  		NV_Ith_S( ((bmnvec*) (m_world->solverSettings))->abstol,XC+i )  = ATOL1*m_world->Values[m_ncoprops*poolVal+M0];
			NV_Ith_S( ((bmnvec*) (m_world->solverSettings))->abstol,ZC+i )  = ATOL3*m_world->Values[m_ncoprops*poolVal+M0];
		}

		NV_Ith_S( ((bmnvec*) (m_world->solverSettings))->abstol,YC+i ) = ATOL2;
		poolVal++;

    }
	
    int flag;
#ifndef CVODE26
    flag = CVodeReInit(m_cvode_mem,bloch,0,((bmnvec*) (m_world->solverSettings))->y,CV_SV,m_reltol,((bmnvec*) (m_world->solverSettings))->abstol);
#else
    flag = CVodeReInit(m_cvode_mem,0,((bmnvec*) (m_world->solverSettings))->y);
#endif
    if(flag != CV_SUCCESS ) {
    	cout << "CVodeReInit failed! aborting..." << endl;
    	if (flag == CV_MEM_NULL) cout << "MEM_NULL"<<endl;
    	if (flag == CV_NO_MALLOC) cout << "CV_NO_MALLOC"<<endl;
    	if (flag == CV_ILL_INPUT) cout << "CV_ILL_INPUT"<<endl;
		
    	exit (-1);
    }
	
}
Exemplo n.º 29
0
void CvodeSolver::initialize(const double &pVoiStart, const int &pStatesCount,
                             double *pConstants, double *pStates,
                             double *pRates, double *pAlgebraic,
                             ComputeRatesFunction pComputeRates)
{
    if (!mSolver) {
        // Initialise the ODE solver itself

        OpenCOR::CoreSolver::CoreOdeSolver::initialize(pVoiStart, pStatesCount,
                                                       pConstants, pStates,
                                                       pRates, pAlgebraic,
                                                       pComputeRates);

        // Retrieve some of the CVODE properties

        if (mProperties.contains(MaximumStepProperty)) {
            mMaximumStep = mProperties.value(MaximumStepProperty).toDouble();
        } else {
            emit error(QObject::tr("the 'maximum step' property value could not be retrieved"));

            return;
        }

        if (mProperties.contains(MaximumNumberOfStepsProperty)) {
            mMaximumNumberOfSteps = mProperties.value(MaximumNumberOfStepsProperty).toInt();
        } else {
            emit error(QObject::tr("the 'maximum number of steps' property value could not be retrieved"));

            return;
        }

        if (mProperties.contains(RelativeToleranceProperty)) {
            mRelativeTolerance = mProperties.value(RelativeToleranceProperty).toDouble();
        } else {
            emit error(QObject::tr("the 'relative tolerance' property value could not be retrieved"));

            return;
        }

        if (mProperties.contains(AbsoluteToleranceProperty)) {
            mAbsoluteTolerance = mProperties.value(AbsoluteToleranceProperty).toDouble();
        } else {
            emit error(QObject::tr("the 'absolute tolerance' property value could not be retrieved"));

            return;
        }

        // Create the states vector

        mStatesVector = N_VMake_Serial(pStatesCount, pStates);

        // Create the CVODE solver

        mSolver = CVodeCreate(CV_BDF, CV_NEWTON);

        // Use our own error handler

        CVodeSetErrHandlerFn(mSolver, errorHandler, this);

        // Initialise the CVODE solver

        CVodeInit(mSolver, rhsFunction, pVoiStart, mStatesVector);

        // Set some user data

        delete mUserData;   // Just in case the solver got initialised before

        mUserData = new CvodeSolverUserData(pConstants, pAlgebraic,
                                            pComputeRates);

        CVodeSetUserData(mSolver, mUserData);

        // Set the linear solver

        CVDense(mSolver, pStatesCount);

        // Set the maximum step

        CVodeSetMaxStep(mSolver, mMaximumStep);

        // Set the maximum number of steps

        CVodeSetMaxNumSteps(mSolver, mMaximumNumberOfSteps);

        // Set the relative and absolute tolerances

        CVodeSStolerances(mSolver, mRelativeTolerance, mAbsoluteTolerance);
    } else {
        // Reinitialise the CVODE object

        CVodeReInit(mSolver, pVoiStart, mStatesVector);
    }
}