void FCV_REINIT(realtype *t0, realtype *y0, int *iatol, realtype *rtol, realtype *atol, int *ier) { N_Vector Vatol; *ier = 0; /* Initialize all pointers to NULL */ Vatol = NULL; /* Set data in F2C_CVODE_vec to y0 */ N_VSetArrayPointer(y0, F2C_CVODE_vec); /* Call CVReInit */ *ier = CVodeReInit(CV_cvodemem, *t0, F2C_CVODE_vec); /* Reset data pointers */ N_VSetArrayPointer(NULL, F2C_CVODE_vec); /* On failure, exit */ if (*ier != CV_SUCCESS) { *ier = -1; return; } /* Set tolerances */ switch (*iatol) { case 1: *ier = CVodeSStolerances(CV_cvodemem, *rtol, *atol); break; case 2: Vatol = NULL; Vatol = N_VCloneEmpty(F2C_CVODE_vec); if (Vatol == NULL) { *ier = -1; return; } N_VSetArrayPointer(atol, Vatol); *ier = CVodeSVtolerances(CV_cvodemem, *rtol, Vatol); N_VDestroy(Vatol); break; } /* On failure, exit */ if (*ier != CV_SUCCESS) { *ier = -1; return; } return; }
void ode_solver_setErrTol(ode_solver* solver, const double rel_tol, double* abs_tol, const int abs_tol_len){ if( (abs_tol_len != 1) && (abs_tol_len != solver->odeModel->N)){ fprintf(stderr,"ode_solver_setErrTol: length of abs_tol must be 1 or equal to the number of variables in the ode model.\n"); return ; } /* set tollerances to the cvode_mem internal structure */ if ( abs_tol_len == 1 ) CVodeSStolerances(solver->cvode_mem, rel_tol, abs_tol[0]); else{ N_Vector abs_tol_vec = N_VNewEmpty_Serial(abs_tol_len); /* alloc */ NV_DATA_S(abs_tol_vec) = abs_tol; CVodeSVtolerances(solver->cvode_mem, rel_tol, abs_tol_vec); N_VDestroy_Serial(abs_tol_vec); /* free */ } }
int main(int narg, char **args) { realtype reltol, t, tout; N_Vector state, abstol; void *cvode_mem; int flag, flagr; int rootsfound[NRF]; int rootdir[] = {1,}; FILE *pout; if(!(pout = fopen("results/iaf_v.dat", "w"))){ fprintf(stderr, "Cannot open file results/iaf_v.dat. Are you trying to write to a non-existent directory? Exiting...\n"); exit(1); } state = abstol = NULL; cvode_mem = NULL; state = N_VNew_Serial(NEQ); if (check_flag((void *)state, "N_VNew_Serial", 0)) return(1); abstol = N_VNew_Serial(NEQ); if (check_flag((void *)abstol, "N_VNew_Serial", 0)) return(1); realtype reset = -0.07; realtype C = 3.2e-12; realtype thresh = -0.055; realtype gleak = 2e-10; realtype eleak = -0.053; realtype p[] = {reset, C, thresh, gleak, eleak, }; realtype v = reset; NV_Ith_S(state, 0) = reset; reltol = RTOL; NV_Ith_S(abstol,0) = ATOL0; /* Allocations and initializations */ cvode_mem = CVodeCreate(CV_BDF, CV_NEWTON); if (check_flag((void *)cvode_mem, "CVodeCreate", 0)) return(1); flag = CVodeInit(cvode_mem, dstate_dt, T0, state); if (check_flag(&flag, "CVodeInit", 1)) return(1); flag = CVodeSetUserData(cvode_mem, p); if (check_flag(&flag, "CVodeSetUserData", 1)) return(1); flag = CVodeSVtolerances(cvode_mem, reltol, abstol); if (check_flag(&flag, "CVodeSVtolerances", 1)) return(1); flag = CVodeRootInit(cvode_mem, NRF, root_functions); if (check_flag(&flag, "CVodeRootInit", 1)) return(1); CVodeSetRootDirection(cvode_mem, rootdir); if (check_flag(&flag, "CVodeSetRootDirection", 1)) return(1); flag = CVDense(cvode_mem, NEQ); if (check_flag(&flag, "CVDense", 1)) return(1); printf(" \n Integrating iaf \n\n"); printf("#t v, \n"); PrintOutput(pout, t, state); tout = DT; while(1) { flag = CVode(cvode_mem, tout, state, &t, CV_NORMAL); if(flag == CV_ROOT_RETURN) { /* Event detected */ flagr = CVodeGetRootInfo(cvode_mem, rootsfound); if (check_flag(&flagr, "CVodeGetRootInfo", 1)) return(1); PrintRootInfo(t, state, rootsfound); if(rootsfound[0]){ //condition_0 v = NV_Ith_S(state, 0); NV_Ith_S(state, 0) = reset; } /* Restart integration with event-corrected state */ flag = CVodeSetUserData(cvode_mem, p); if (check_flag(&flag, "CVodeSetUserData", 1)) return(1); CVodeReInit(cvode_mem, t, state); //PrintRootInfo(t, state, rootsfound); } else { PrintOutput(pout, t, state); if(check_flag(&flag, "CVode", 1)) break; if(flag == CV_SUCCESS) { tout += DT; } if (t >= T1) break; } } PrintFinalStats(cvode_mem); N_VDestroy_Serial(state); N_VDestroy_Serial(abstol); CVodeFree(&cvode_mem); fclose(pout); return(0); }
int do_integrate(float t_start, float t_stop, int n_points) { realtype reltol, t; N_Vector y, abstol; void *cvode_mem; int flag, flagr, iout; y = abstol = NULL; cvode_mem = NULL; /* Create serial vector of length NEQ for I.C. and abstol */ y = N_VNew_Serial(NEQ); if (check_flag((void *)y, "N_VNew_Serial", 0)) return(1); abstol = N_VNew_Serial(NEQ); if (check_flag((void *)abstol, "N_VNew_Serial", 0)) return(1); //Setup the initial state values: setup_initial_states(y); setup_tolerances(abstol); /* Set the scalar relative tolerance */ reltol = RTOL; /* Call CVodeCreate to create the solver memory and specify the * Backward Differentiation Formula and the use of a Newton iteration */ cvode_mem = CVodeCreate(CV_BDF, CV_NEWTON); if (check_flag((void *)cvode_mem, "CVodeCreate", 0)) return(1); /* Call CVodeInit to initialize the integrator memory and specify the * user's right hand side function in y'=f(t,y), the inital time T0, and * the initial dependent variable vector y. */ flag = CVodeInit(cvode_mem, f, t_start, y); if (check_flag(&flag, "CVodeInit", 1)) return(1); /* Call CVodeSVtolerances to specify the scalar relative tolerance * and vector absolute tolerances */ flag = CVodeSVtolerances(cvode_mem, reltol, abstol); if (check_flag(&flag, "CVodeSVtolerances", 1)) return(1); /* Call CVDense to specify the CVDENSE dense linear solver */ flag = CVDense(cvode_mem, NEQ); if (check_flag(&flag, "CVDense", 1)) return(1); /* Set the Jacobian routine to Jac (user-supplied) */ flag = CVDlsSetDenseJacFn(cvode_mem, Jac); if (check_flag(&flag, "CVDlsSetDenseJacFn", 1)) return(1); /* In loop, call CVode, print results, and test for error.*/ printf(" \n3-species kinetics problem\n\n"); iout = 0; int i=0; for(i=1;i< n_points; i++) { float t_next = t_start + (t_stop-t_start)/n_points * i; printf("Advancing to: %f", t_next); flag = CVode(cvode_mem, t_next, y, &t, CV_NORMAL); loop_function(t,y); PrintOutput(t, Ith(y,1), Ith(y,2), Ith(y,3)); //printf("MH: %d %f",iout,t_next); if (check_flag(&flag, "CVode", 1)) break; assert(flag==CV_SUCCESS); } /* Print some final statistics */ PrintFinalStats(cvode_mem); /* Free y and abstol vectors */ N_VDestroy_Serial(y); N_VDestroy_Serial(abstol); /* Free integrator memory */ CVodeFree(&cvode_mem); return(0); }
int main() { realtype reltol, t, tout; N_Vector y, abstol; void *cvode_mem; int flag, flagr, iout, nnz; int rootsfound[2]; y = abstol = NULL; cvode_mem = NULL; /* Create serial vector of length NEQ for I.C. and abstol */ y = N_VNew_Serial(NEQ); if (check_flag((void *)y, "N_VNew_Serial", 0)) return(1); abstol = N_VNew_Serial(NEQ); if (check_flag((void *)abstol, "N_VNew_Serial", 0)) return(1); /* Initialize y */ Ith(y,1) = Y1; Ith(y,2) = Y2; Ith(y,3) = Y3; /* Set the scalar relative tolerance */ reltol = RTOL; /* Set the vector absolute tolerance */ Ith(abstol,1) = ATOL1; Ith(abstol,2) = ATOL2; Ith(abstol,3) = ATOL3; /* Call CVodeCreate to create the solver memory and specify the * Backward Differentiation Formula and the use of a Newton iteration */ cvode_mem = CVodeCreate(CV_BDF, CV_NEWTON); if (check_flag((void *)cvode_mem, "CVodeCreate", 0)) return(1); /* Call CVodeInit to initialize the integrator memory and specify the * user's right hand side function in y'=f(t,y), the inital time T0, and * the initial dependent variable vector y. */ flag = CVodeInit(cvode_mem, f, T0, y); if (check_flag(&flag, "CVodeInit", 1)) return(1); /* Call CVodeSVtolerances to specify the scalar relative tolerance * and vector absolute tolerances */ flag = CVodeSVtolerances(cvode_mem, reltol, abstol); if (check_flag(&flag, "CVodeSVtolerances", 1)) return(1); /* Call CVodeRootInit to specify the root function g with 2 components */ flag = CVodeRootInit(cvode_mem, 2, g); if (check_flag(&flag, "CVodeRootInit", 1)) return(1); /* Call CVSuperLUMT to specify the CVSuperLUMT sparse direct linear solver */ nnz = NEQ * NEQ; flag = CVSuperLUMT(cvode_mem, 1, NEQ, nnz); if (check_flag(&flag, "CVSuperLUMT", 1)) return(1); /* Set the Jacobian routine to Jac (user-supplied) */ flag = CVSlsSetSparseJacFn(cvode_mem, Jac); if (check_flag(&flag, "CVSlsSetSparseJacFn", 1)) return(1); /* In loop, call CVode, print results, and test for error. Break out of loop when NOUT preset output times have been reached. */ printf(" \n3-species kinetics problem\n\n"); iout = 0; tout = T1; while(1) { flag = CVode(cvode_mem, tout, y, &t, CV_NORMAL); PrintOutput(t, Ith(y,1), Ith(y,2), Ith(y,3)); if (flag == CV_ROOT_RETURN) { flagr = CVodeGetRootInfo(cvode_mem, rootsfound); if (check_flag(&flagr, "CVodeGetRootInfo", 1)) return(1); PrintRootInfo(rootsfound[0],rootsfound[1]); } if (check_flag(&flag, "CVode", 1)) break; if (flag == CV_SUCCESS) { iout++; tout *= TMULT; } if (iout == NOUT) break; } /* Print some final statistics */ PrintFinalStats(cvode_mem); /* Free y and abstol vectors */ N_VDestroy_Serial(y); N_VDestroy_Serial(abstol); /* Free integrator memory */ CVodeFree(&cvode_mem); return(0); }
void CVodesIntegrator::initialize(double t0, FuncEval& func) { m_neq = func.neq(); m_t0 = t0; if (m_y) { N_VDestroy_Serial(nv(m_y)); // free solution vector if already allocated } m_y = reinterpret_cast<void*>(N_VNew_Serial(m_neq)); // allocate solution vector for (int i=0; i<m_neq; i++) { NV_Ith_S(nv(m_y), i) = 0.0; } // check abs tolerance array size if (m_itol == CV_SV && m_nabs < m_neq) throw CVodesErr("not enough absolute tolerance values specified."); func.getInitialConditions(m_t0, m_neq, NV_DATA_S(nv(m_y))); if (m_cvode_mem) CVodeFree(&m_cvode_mem); /* * Specify the method and the iteration type: * Cantera Defaults: * CV_BDF - Use BDF methods * CV_NEWTON - use newton's method */ m_cvode_mem = CVodeCreate(m_method, m_iter); if (!m_cvode_mem) throw CVodesErr("CVodeCreate failed."); int flag = 0; #if defined(SUNDIALS_VERSION_22) || defined(SUNDIALS_VERSION_23) if (m_itol == CV_SV) { // vector atol flag = CVodeMalloc(m_cvode_mem, cvodes_rhs, m_t0, nv(m_y), m_itol, m_reltol, nv(m_abstol)); } else { // scalar atol flag = CVodeMalloc(m_cvode_mem, cvodes_rhs, m_t0, nv(m_y), m_itol, m_reltol, &m_abstols); } if (flag != CV_SUCCESS) { if (flag == CV_MEM_FAIL) { throw CVodesErr("Memory allocation failed."); } else if (flag == CV_ILL_INPUT) { throw CVodesErr("Illegal value for CVodeMalloc input argument."); } else throw CVodesErr("CVodeMalloc failed."); } #elif defined(SUNDIALS_VERSION_24) flag = CVodeInit(m_cvode_mem, cvodes_rhs, m_t0, nv(m_y)); if (flag != CV_SUCCESS) { if (flag == CV_MEM_FAIL) { throw CVodesErr("Memory allocation failed."); } else if (flag == CV_ILL_INPUT) { throw CVodesErr("Illegal value for CVodeInit input argument."); } else { throw CVodesErr("CVodeInit failed."); } } if (m_itol == CV_SV) { flag = CVodeSVtolerances(m_cvode_mem, m_reltol, nv(m_abstol)); } else { flag = CVodeSStolerances(m_cvode_mem, m_reltol, m_abstols); } if (flag != CV_SUCCESS) { if (flag == CV_MEM_FAIL) { throw CVodesErr("Memory allocation failed."); } else if (flag == CV_ILL_INPUT) { throw CVodesErr("Illegal value for CVodeInit input argument."); } else { throw CVodesErr("CVodeInit failed."); } } #else printf("unknown sundials verson\n"); exit(-1); #endif if (m_type == DENSE + NOJAC) { long int N = m_neq; CVDense(m_cvode_mem, N); } else if (m_type == DIAG) { CVDiag(m_cvode_mem); } else if (m_type == GMRES) { CVSpgmr(m_cvode_mem, PREC_NONE, 0); } else if (m_type == BAND + NOJAC) { long int N = m_neq; long int nu = m_mupper; long int nl = m_mlower; CVBand(m_cvode_mem, N, nu, nl); } else { throw CVodesErr("unsupported option"); } // pass a pointer to func in m_data m_fdata = new FuncData(&func, func.nparams()); //m_data = (void*)&func; #if defined(SUNDIALS_VERSION_22) || defined(SUNDIALS_VERSION_23) flag = CVodeSetFdata(m_cvode_mem, (void*)m_fdata); if (flag != CV_SUCCESS) { throw CVodesErr("CVodeSetFdata failed."); } #elif defined(SUNDIALS_VERSION_24) flag = CVodeSetUserData(m_cvode_mem, (void*)m_fdata); if (flag != CV_SUCCESS) { throw CVodesErr("CVodeSetUserData failed."); } #endif if (func.nparams() > 0) { sensInit(t0, func); flag = CVodeSetSensParams(m_cvode_mem, DATA_PTR(m_fdata->m_pars), NULL, NULL); } // set options if (m_maxord > 0) flag = CVodeSetMaxOrd(m_cvode_mem, m_maxord); if (m_maxsteps > 0) flag = CVodeSetMaxNumSteps(m_cvode_mem, m_maxsteps); if (m_hmax > 0) flag = CVodeSetMaxStep(m_cvode_mem, m_hmax); }
Bloch_McConnell_CV_Model::Bloch_McConnell_CV_Model () { m_world->solverSettings = new bmnvec; /* for (int i=0;i<OPT_SIZE;i++) {m_iopt[i]=0; m_ropt[i]=0.0;} m_iopt[MXSTEP] = 1000000; m_ropt[HMAX] = 10000.0;// the maximum stepsize in msec of the integrator*/ m_reltol = RTOL; //cvode2.5: // create cvode memory pointer; no mallocs done yet. // m_cvode_mem = CVodeCreate(CV_BDF,CV_NEWTON); m_cvode_mem = CVodeCreate(CV_ADAMS,CV_FUNCTIONAL); // cvode allocate memory. // do CVodeMalloc with dummy values y0,abstol once here; // -> CVodeReInit can later be used //HACK int pools = m_world->GetNoOfCompartments(); N_Vector y0,abstol; y0 = N_VNew_Serial(NEQ*pools); abstol = N_VNew_Serial(NEQ*pools); ((bmnvec*) (m_world->solverSettings))->abstol = N_VNew_Serial(pools*NEQ); for(int i = 0; i< pools*NEQ; i+=NEQ){ NV_Ith_S(y0,AMPL+i) = 0.0; NV_Ith_S(y0,PHASE+i) = 0.0; NV_Ith_S(y0,ZC+i) = 0.0; NV_Ith_S(abstol,AMPL+i) = ATOL1; NV_Ith_S(abstol,PHASE+i) = ATOL2; NV_Ith_S(abstol,ZC+i) = ATOL3; } #ifndef CVODE26 if(CVodeMalloc(m_cvode_mem,bloch,0,y0,CV_SV,m_reltol,abstol) != CV_SUCCESS ) { cout << "CVodeMalloc failed! aborting..." << endl;exit (-1); } if(CVodeSetFdata(m_cvode_mem, (void *) m_world) !=CV_SUCCESS) { cout << "CVode function data could not be set. Panic!" << endl;exit (-1); } #else if(CVodeInit(m_cvode_mem,bloch,0,y0) != CV_SUCCESS ) { cout << "CVodeInit failed! aborting..." << endl;exit (-1); } if(CVodeSVtolerances(m_cvode_mem, m_reltol, abstol)!= CV_SUCCESS){ cout << "CVodeSVtolerances failed! aborting..." << endl;exit (-1); } if(CVodeSetUserData(m_cvode_mem, (void *) m_world) !=CV_SUCCESS) { cout << "CVode function data could not be set. Panic!" << endl;exit (-1); } #endif /* int flag; int blub = (3*pools); flag = CVDense(m_cvode_mem, blub); if (flag == CVDENSE_SUCCESS) cout<< "great" <<endl; else cout<< "bad" <<endl; */ N_VDestroy_Serial(y0); N_VDestroy_Serial(abstol); /*if(CVodeSetFdata(m_cvode_mem, (void *) m_world) !=CV_SUCCESS) { cout << "CVode function data could not be set. Panic!" << endl; exit (-1); } // set CVODE initial step size // CVodeSetInitStep(m_cvode_mem, 1e-4); // set CVODE maximum step size CVodeSetMaxErrTestFails(m_cvode_mem, 10); // set CVODE minimum step size CVodeSetMinStep(m_cvode_mem, 1e-15); */ CVodeSetMaxNumSteps(m_cvode_mem, 10000000); // maximum number of warnings t+h = t (if number negative -> no warnings are issued ) CVodeSetMaxHnilWarns(m_cvode_mem,2); }
int main(int narg, char **args) { realtype reltol, t, tout; N_Vector state, abstol; void *cvode_mem; int flag, flagr; int rootsfound[NRF]; int rootdir[] = {1,1,1,}; FILE *pout; pout = stdout; state = abstol = NULL; cvode_mem = NULL; state = N_VNew_Serial(NEQ); if (check_flag((void *)state, "N_VNew_Serial", 0)) return(1); abstol = N_VNew_Serial(NEQ); if (check_flag((void *)abstol, "N_VNew_Serial", 0)) return(1); realtype a = 0.02; realtype b = 0.2; realtype c = -50; realtype d = 2; realtype I = 0; realtype v0 = -70; realtype p[] = {a, b, c, d, I, v0, }; realtype v = v0; realtype u = b * v0; NV_Ith_S(state, 0) = v0; NV_Ith_S(state, 1) = b * v0; reltol = RTOL; NV_Ith_S(abstol,0) = ATOL0; NV_Ith_S(abstol,1) = ATOL1; /* Allocations and initializations */ cvode_mem = CVodeCreate(CV_BDF, CV_NEWTON); if (check_flag((void *)cvode_mem, "CVodeCreate", 0)) return(1); flag = CVodeInit(cvode_mem, dstate_dt, T0, state); if (check_flag(&flag, "CVodeInit", 1)) return(1); flag = CVodeSetUserData(cvode_mem, p); if (check_flag(&flag, "CVodeSetUserData", 1)) return(1); flag = CVodeSVtolerances(cvode_mem, reltol, abstol); if (check_flag(&flag, "CVodeSVtolerances", 1)) return(1); flag = CVodeRootInit(cvode_mem, NRF, root_functions); if (check_flag(&flag, "CVodeRootInit", 1)) return(1); CVodeSetRootDirection(cvode_mem, rootdir); if (check_flag(&flag, "CVodeSetRootDirection", 1)) return(1); flag = CVDense(cvode_mem, NEQ); if (check_flag(&flag, "CVDense", 1)) return(1); printf(" \n Integrating izhikevich_burster \n\n"); printf("#t v, u, \n"); PrintOutput(pout, t, state); tout = DT; while(1) { flag = CVode(cvode_mem, tout, state, &t, CV_NORMAL); if(flag == CV_ROOT_RETURN) { /* Event detected */ flagr = CVodeGetRootInfo(cvode_mem, rootsfound); if (check_flag(&flagr, "CVodeGetRootInfo", 1)) return(1); PrintRootInfo(t, state, rootsfound); if(rootsfound[0]){ //spike v = NV_Ith_S(state, 0); u = NV_Ith_S(state, 1); NV_Ith_S(state, 0) = c; NV_Ith_S(state, 1) = u + d; } if(rootsfound[1]){ //start_inj I = 5; p[0] = a; p[1] = b; p[2] = c; p[3] = d; p[4] = I; p[5] = v0; } if(rootsfound[2]){ //end_inj I = 0; p[0] = a; p[1] = b; p[2] = c; p[3] = d; p[4] = I; p[5] = v0; } /* Restart integration with event-corrected state */ flag = CVodeSetUserData(cvode_mem, p); if (check_flag(&flag, "CVodeSetUserData", 1)) return(1); CVodeReInit(cvode_mem, t, state); //PrintRootInfo(t, state, rootsfound); } else { PrintOutput(pout, t, state); if(check_flag(&flag, "CVode", 1)) break; if(flag == CV_SUCCESS) { tout += DT; } if (t >= T1) break; } } PrintFinalStats(cvode_mem); N_VDestroy_Serial(state); N_VDestroy_Serial(abstol); CVodeFree(&cvode_mem); fclose(pout); return(0); }
void CVodesIntegrator::initialize(double t0, FuncEval& func) { m_neq = func.neq(); m_t0 = t0; m_time = t0; if (m_y) { N_VDestroy_Serial(m_y); // free solution vector if already allocated } m_y = N_VNew_Serial(static_cast<sd_size_t>(m_neq)); // allocate solution vector for (size_t i = 0; i < m_neq; i++) { NV_Ith_S(m_y, i) = 0.0; } // check abs tolerance array size if (m_itol == CV_SV && m_nabs < m_neq) { throw CVodesErr("not enough absolute tolerance values specified."); } func.getInitialConditions(m_t0, m_neq, NV_DATA_S(m_y)); if (m_cvode_mem) { CVodeFree(&m_cvode_mem); } /* * Specify the method and the iteration type: * Cantera Defaults: * CV_BDF - Use BDF methods * CV_NEWTON - use Newton's method */ m_cvode_mem = CVodeCreate(m_method, m_iter); if (!m_cvode_mem) { throw CVodesErr("CVodeCreate failed."); } int flag = CVodeInit(m_cvode_mem, cvodes_rhs, m_t0, m_y); if (flag != CV_SUCCESS) { if (flag == CV_MEM_FAIL) { throw CVodesErr("Memory allocation failed."); } else if (flag == CV_ILL_INPUT) { throw CVodesErr("Illegal value for CVodeInit input argument."); } else { throw CVodesErr("CVodeInit failed."); } } CVodeSetErrHandlerFn(m_cvode_mem, &cvodes_err, this); if (m_itol == CV_SV) { flag = CVodeSVtolerances(m_cvode_mem, m_reltol, m_abstol); } else { flag = CVodeSStolerances(m_cvode_mem, m_reltol, m_abstols); } if (flag != CV_SUCCESS) { if (flag == CV_MEM_FAIL) { throw CVodesErr("Memory allocation failed."); } else if (flag == CV_ILL_INPUT) { throw CVodesErr("Illegal value for CVodeInit input argument."); } else { throw CVodesErr("CVodeInit failed."); } } // pass a pointer to func in m_data m_fdata.reset(new FuncData(&func, func.nparams())); flag = CVodeSetUserData(m_cvode_mem, m_fdata.get()); if (flag != CV_SUCCESS) { throw CVodesErr("CVodeSetUserData failed."); } if (func.nparams() > 0) { sensInit(t0, func); flag = CVodeSetSensParams(m_cvode_mem, m_fdata->m_pars.data(), NULL, NULL); } applyOptions(); }
void Cvode::initialize() { _properties = dynamic_cast<ISystemProperties*>(_system); _continuous_system = dynamic_cast<IContinuous*>(_system); _event_system = dynamic_cast<IEvent*>(_system); _mixed_system = dynamic_cast<IMixedSystem*>(_system); _time_system = dynamic_cast<ITime*>(_system); IGlobalSettings* global_settings = dynamic_cast<ISolverSettings*>(_cvodesettings)->getGlobalSettings(); // Kennzeichnung, dass initialize()() (vor der Integration) aufgerufen wurde _idid = 5000; _tLastEvent = 0.0; _event_n = 0; SolverDefaultImplementation::initialize(); _dimSys = _continuous_system->getDimContinuousStates(); _dimZeroFunc = _event_system->getDimZeroFunc(); if (_dimSys == 0) _dimSys = 1; // introduce dummy state if (_dimSys <= 0) { _idid = -1; throw ModelicaSimulationError(SOLVER,"Cvode::initialize()"); } else { // Allocate state vectors, stages and temporary arrays if (_z) delete[] _z; if (_zInit) delete[] _zInit; if (_zWrite) delete[] _zWrite; if (_zeroSign) delete[] _zeroSign; if (_absTol) delete[] _absTol; if(_delta) delete [] _delta; if(_deltaInv) delete [] _deltaInv; if(_ysave) delete [] _ysave; _z = new double[_dimSys]; _zInit = new double[_dimSys]; _zWrite = new double[_dimSys]; _zeroSign = new int[_dimZeroFunc]; _absTol = new double[_dimSys]; _delta =new double[_dimSys]; _deltaInv =new double[_dimSys]; _ysave =new double[_dimSys]; memset(_z, 0, _dimSys * sizeof(double)); memset(_zInit, 0, _dimSys * sizeof(double)); memset(_ysave, 0, _dimSys * sizeof(double)); // Counter initialisieren _outStps = 0; if (_cvodesettings->getDenseOutput()) { // Ausgabeschrittweite _hOut = global_settings->gethOutput(); } // Allocate memory for the solver _cvodeMem = CVodeCreate(CV_BDF, CV_NEWTON); if (check_flag((void*) _cvodeMem, "CVodeCreate", 0)) { _idid = -5; throw ModelicaSimulationError(SOLVER,/*_idid,_tCurrent,*/"Cvode::initialize()"); } // // Make Cvode ready for integration // // Set initial values for CVODE _continuous_system->evaluateAll(IContinuous::CONTINUOUS); _continuous_system->getContinuousStates(_zInit); memcpy(_z, _zInit, _dimSys * sizeof(double)); // Get nominal values _absTol[0] = 1.0; // in case of dummy state _continuous_system->getNominalStates(_absTol); for (int i = 0; i < _dimSys; i++) _absTol[i] *= dynamic_cast<ISolverSettings*>(_cvodesettings)->getATol(); _CV_y0 = N_VMake_Serial(_dimSys, _zInit); _CV_y = N_VMake_Serial(_dimSys, _z); _CV_yWrite = N_VMake_Serial(_dimSys, _zWrite); _CV_absTol = N_VMake_Serial(_dimSys, _absTol); if (check_flag((void*) _CV_y0, "N_VMake_Serial", 0)) { _idid = -5; throw ModelicaSimulationError(SOLVER,"Cvode::initialize()"); } // Initialize Cvode (Initial values are required) _idid = CVodeInit(_cvodeMem, CV_fCallback, _tCurrent, _CV_y0); if (_idid < 0) { _idid = -5; throw ModelicaSimulationError(SOLVER,"Cvode::initialize()"); } // Set Tolerances _idid = CVodeSVtolerances(_cvodeMem, dynamic_cast<ISolverSettings*>(_cvodesettings)->getRTol(), _CV_absTol); // RTOL and ATOL if (_idid < 0) throw ModelicaSimulationError(SOLVER,"CVode::initialize()"); // Set the pointer to user-defined data _idid = CVodeSetUserData(_cvodeMem, _data); if (_idid < 0) throw ModelicaSimulationError(SOLVER,"Cvode::initialize()"); _idid = CVodeSetInitStep(_cvodeMem, 1e-6); // INITIAL STEPSIZE if (_idid < 0) throw ModelicaSimulationError(SOLVER,"Cvode::initialize()"); _idid = CVodeSetMaxOrd(_cvodeMem, 5); // Max Order if (_idid < 0) throw ModelicaSimulationError(SOLVER,"CVoder::initialize()"); _idid = CVodeSetMaxConvFails(_cvodeMem, 100); // Maximale Fehler im Konvergenztest if (_idid < 0) throw ModelicaSimulationError(SOLVER,"CVoder::initialize()"); _idid = CVodeSetStabLimDet(_cvodeMem, TRUE); // Stability Detection if (_idid < 0) throw ModelicaSimulationError(SOLVER,"CVoder::initialize()"); _idid = CVodeSetMinStep(_cvodeMem, dynamic_cast<ISolverSettings*>(_cvodesettings)->getLowerLimit()); // MINIMUM STEPSIZE if (_idid < 0) throw ModelicaSimulationError(SOLVER,"CVode::initialize()"); _idid = CVodeSetMaxStep(_cvodeMem, global_settings->getEndTime() / 10.0); // MAXIMUM STEPSIZE if (_idid < 0) throw ModelicaSimulationError(SOLVER,"CVode::initialize()"); _idid = CVodeSetMaxNonlinIters(_cvodeMem, 5); // Max number of iterations if (_idid < 0) throw ModelicaSimulationError(SOLVER,"CVode::initialize()"); _idid = CVodeSetMaxErrTestFails(_cvodeMem, 100); if (_idid < 0) throw ModelicaSimulationError(SOLVER,"CVode::initialize()"); _idid = CVodeSetMaxNumSteps(_cvodeMem, 1e3); // Max Number of steps if (_idid < 0) throw ModelicaSimulationError(SOLVER,/*_idid,_tCurrent,*/"Cvode::initialize()"); // Initialize linear solver #ifdef USE_SUNDIALS_LAPACK _idid = CVLapackDense(_cvodeMem, _dimSys); #else _idid = CVDense(_cvodeMem, _dimSys); #endif if (_idid < 0) throw ModelicaSimulationError(SOLVER,"Cvode::initialize()"); // Use own jacobian matrix // Check if Colored Jacobians are worth to use #if SUNDIALS_MAJOR_VERSION >= 2 || (SUNDIALS_MAJOR_VERSION == 2 && SUNDIALS_MINOR_VERSION >= 4) _maxColors = _system->getAMaxColors(); if(_maxColors < _dimSys && _continuous_system->getDimContinuousStates() > 0) { // _idid = CVDlsSetDenseJacFn(_cvodeMem, &CV_JCallback); // initializeColoredJac(); } #endif if (_idid < 0) throw ModelicaSimulationError(SOLVER,"CVode::initialize()"); if (_dimZeroFunc) { _idid = CVodeRootInit(_cvodeMem, _dimZeroFunc, &CV_ZerofCallback); memset(_zeroSign, 0, _dimZeroFunc * sizeof(int)); _idid = CVodeSetRootDirection(_cvodeMem, _zeroSign); if (_idid < 0) throw ModelicaSimulationError(SOLVER,/*_idid,_tCurrent,*/"CVode::initialize()"); memset(_zeroSign, -1, _dimZeroFunc * sizeof(int)); memset(_zeroVal, -1, _dimZeroFunc * sizeof(int)); } _cvode_initialized = true; LOGGER_WRITE("Cvode: initialized",LC_SOLV,LL_DEBUG); } }
/** \brief Call the ODE solver. * * \param neq The number of equations. * \param x_f A pointer to a vector of \c neq variables, giving the * initial state vector on entry and the final state vector on exit. * \param abstol_f A pointer to a vector of \c neq variables, giving * the absolute error tolerance for the corresponding state vector * component. * \param reltol_f The scalar relative tolerance. * \param t_initial_f The initial time (s). * \param t_final_f The final time (s). * \return A result code (0 is success). */ int condense_solver(int neq, double *x_f, double *abstol_f, double reltol_f, double t_initial_f, double t_final_f) { realtype reltol, t_initial, t_final, t, tout; N_Vector y, abstol; void *cvode_mem; CVodeMem cv_mem; int flag, i, pretype, maxl; realtype *y_data, *abstol_data; y = abstol = NULL; cvode_mem = NULL; y = N_VNew_Serial(neq); if (condense_check_flag((void *)y, "N_VNew_Serial", 0)) return PMC_CONDENSE_SOLVER_INIT_Y; abstol = N_VNew_Serial(neq); if (condense_check_flag((void *)abstol, "N_VNew_Serial", 0)) return PMC_CONDENSE_SOLVER_INIT_ABSTOL; y_data = NV_DATA_S(y); abstol_data = NV_DATA_S(abstol); for (i = 0; i < neq; i++) { y_data[i] = x_f[i]; abstol_data[i] = abstol_f[i]; } reltol = reltol_f; t_initial = t_initial_f; t_final = t_final_f; cvode_mem = CVodeCreate(CV_BDF, CV_NEWTON); if (condense_check_flag((void *)cvode_mem, "CVodeCreate", 0)) return PMC_CONDENSE_SOLVER_INIT_CVODE_MEM; flag = CVodeInit(cvode_mem, condense_vf, t_initial, y); if (condense_check_flag(&flag, "CVodeInit", 1)) return PMC_CONDENSE_SOLVER_INIT_CVODE; flag = CVodeSVtolerances(cvode_mem, reltol, abstol); if (condense_check_flag(&flag, "CVodeSVtolerances", 1)) return PMC_CONDENSE_SOLVER_SVTOL; flag = CVodeSetMaxNumSteps(cvode_mem, 100000); if (condense_check_flag(&flag, "CVodeSetMaxNumSteps", 1)) return PMC_CONDENSE_SOLVER_SET_MAX_STEPS; /*******************************************************/ // dense solver //flag = CVDense(cvode_mem, neq); //if (condense_check_flag(&flag, "CVDense", 1)) return(1); /*******************************************************/ /*******************************************************/ // iterative solver //pretype = PREC_LEFT; //maxl = 0; //flag = CVSptfqmr(cvode_mem, pretype, maxl); //if (condense_check_flag(&flag, "CVSptfqmr", 1)) return(1); //flag = CVSpilsSetJacTimesVecFn(cvode_mem, condense_jtimes); //if (condense_check_flag(&flag, "CVSpilsSetJacTimesVecFn", 1)) return(1); //flag = CVSpilsSetPreconditioner(cvode_mem, NULL, condense_prec); //if (condense_check_flag(&flag, "CVSpilsSetPreconditioner", 1)) return(1); /*******************************************************/ /*******************************************************/ // explicit solver cv_mem = (CVodeMem)cvode_mem; cv_mem->cv_linit = condense_solver_Init; cv_mem->cv_lsetup = condense_solver_Setup; cv_mem->cv_lsolve = condense_solver_Solve; cv_mem->cv_lfree = condense_solver_Free; /*******************************************************/ t = t_initial; flag = CVode(cvode_mem, t_final, y, &t, CV_NORMAL); if (condense_check_flag(&flag, "CVode", 1)) return PMC_CONDENSE_SOLVER_FAIL; for (i = 0; i < neq; i++) { x_f[i] = y_data[i]; } N_VDestroy_Serial(y); N_VDestroy_Serial(abstol); CVodeFree(&cvode_mem); return PMC_CONDENSE_SOLVER_SUCCESS; }
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; }
int main(int narg, char **args) { realtype reltol, t, tout; N_Vector state, abstol; void *cvode_mem; int flag, flagr; FILE *pout; if(!(pout = fopen("Locke2008_Circadian_Clock.dat", "w"))){ fprintf(stderr, "Cannot open file Locke2008_Circadian_Clock.dat. Are you trying to write to a non-existent directory? Exiting...\n"); exit(1); } state = abstol = NULL; cvode_mem = NULL; state = N_VNew_Serial(NEQ); if (check_flag((void *)state, "N_VNew_Serial", 0)) return(1); abstol = N_VNew_Serial(NEQ); if (check_flag((void *)abstol, "N_VNew_Serial", 0)) return(1); realtype Kc = 4.8283; realtype v_4 = 1.0841; realtype v_6 = 4.6645; realtype vc = 6.7924; realtype v_1 = 6.8355; realtype v_2 = 8.4297; realtype K = 1.0; realtype v_8 = 3.5216; realtype L = 0.0; realtype n = 5.6645; realtype k3 = 0.1177; realtype K2 = 0.291; realtype K1 = 2.7266; realtype k7 = 0.2282; realtype K6 = 9.9849; realtype k5 = 0.3352; realtype K4 = 8.1343; realtype K8 = 7.4519; realtype init_X1 = 4.25; realtype tscale = 1.0; realtype init_Z1 = 2.25; realtype init_Z2 = 0.0; realtype init_V1 = 2.5; realtype init_V2 = 0.0; realtype init_X2 = 0.0; realtype compartment = 1.0; realtype init_Y1 = 3.25; realtype init_Y2 = 0.0; realtype p[] = {Kc, v_4, v_6, vc, v_1, v_2, K, v_8, L, n, k3, K2, K1, k7, K6, k5, K4, K8, init_X1, tscale, init_Z1, init_Z2, init_V1, init_V2, init_X2, compartment, init_Y1, init_Y2, }; realtype X1 = init_X1; realtype X2 = init_X2; realtype V1 = init_V1; realtype V2 = init_V2; realtype Y1 = init_Y1; realtype Y2 = init_Y2; realtype Z1 = init_Z1; realtype Z2 = init_Z2; NV_Ith_S(state, 0) = init_Y2; NV_Ith_S(state, 1) = init_V1; NV_Ith_S(state, 2) = init_Y1; NV_Ith_S(state, 3) = init_V2; NV_Ith_S(state, 4) = init_X2; NV_Ith_S(state, 5) = init_X1; NV_Ith_S(state, 6) = init_Z1; NV_Ith_S(state, 7) = init_Z2; reltol = RTOL; NV_Ith_S(abstol,0) = ATOL0; NV_Ith_S(abstol,1) = ATOL1; NV_Ith_S(abstol,2) = ATOL2; NV_Ith_S(abstol,3) = ATOL3; NV_Ith_S(abstol,4) = ATOL4; NV_Ith_S(abstol,5) = ATOL5; NV_Ith_S(abstol,6) = ATOL6; NV_Ith_S(abstol,7) = ATOL7; /* Allocations and initializations */ cvode_mem = CVodeCreate(CV_BDF, CV_NEWTON); if (check_flag((void *)cvode_mem, "CVodeCreate", 0)) return(1); flag = CVodeInit(cvode_mem, dstate_dt, T0, state); if (check_flag(&flag, "CVodeInit", 1)) return(1); flag = CVodeSetUserData(cvode_mem, p); if (check_flag(&flag, "CVodeSetUserData", 1)) return(1); flag = CVodeSVtolerances(cvode_mem, reltol, abstol); if (check_flag(&flag, "CVodeSVtolerances", 1)) return(1); flag = CVDense(cvode_mem, NEQ); if (check_flag(&flag, "CVDense", 1)) return(1); printf(" \n Integrating Locke2008_Circadian_Clock_0 \n\n"); printf("#t Y2, V1, Y1, V2, X2, X1, Z1, Z2, \n"); PrintOutput(pout, t, state); tout = DT; while(1) { flag = CVode(cvode_mem, tout, state, &t, CV_NORMAL); { PrintOutput(pout, t, state); if(check_flag(&flag, "CVode", 1)) break; if(flag == CV_SUCCESS) { tout += DT; } if (t >= T1) break; } } PrintFinalStats(cvode_mem); N_VDestroy_Serial(state); N_VDestroy_Serial(abstol); CVodeFree(&cvode_mem); fclose(pout); return(0); }
void FCV_MALLOC(realtype *t0, realtype *y0, int *meth, int *iatol, realtype *rtol, realtype *atol, long int *iout, realtype *rout, long int *ipar, realtype *rpar, int *ier) { int lmm; N_Vector Vatol; FCVUserData CV_userdata; *ier = 0; /* Check for required vector operations */ if(F2C_CVODE_vec->ops->nvgetarraypointer == NULL || F2C_CVODE_vec->ops->nvsetarraypointer == NULL) { *ier = -1; fprintf(stderr, "A required vector operation is not implemented.\n\n"); return; } /* Initialize all pointers to NULL */ CV_cvodemem = NULL; Vatol = NULL; FCVNullNonlinSol(); /* initialize global constants to disable each option */ CV_nrtfn = 0; CV_ls = -1; /* Create CVODE object */ lmm = (*meth == 1) ? CV_ADAMS : CV_BDF; CV_cvodemem = CVodeCreate(lmm); if (CV_cvodemem == NULL) { *ier = -1; return; } /* Set and attach user data */ CV_userdata = NULL; CV_userdata = (FCVUserData) malloc(sizeof *CV_userdata); if (CV_userdata == NULL) { *ier = -1; return; } CV_userdata->rpar = rpar; CV_userdata->ipar = ipar; *ier = CVodeSetUserData(CV_cvodemem, CV_userdata); if(*ier != CV_SUCCESS) { free(CV_userdata); CV_userdata = NULL; *ier = -1; return; } /* Set data in F2C_CVODE_vec to y0 */ N_VSetArrayPointer(y0, F2C_CVODE_vec); /* Call CVodeInit */ *ier = CVodeInit(CV_cvodemem, FCVf, *t0, F2C_CVODE_vec); /* Reset data pointers */ N_VSetArrayPointer(NULL, F2C_CVODE_vec); /* On failure, exit */ if(*ier != CV_SUCCESS) { free(CV_userdata); CV_userdata = NULL; *ier = -1; return; } /* Set tolerances */ switch (*iatol) { case 1: *ier = CVodeSStolerances(CV_cvodemem, *rtol, *atol); break; case 2: Vatol = NULL; Vatol = N_VCloneEmpty(F2C_CVODE_vec); if (Vatol == NULL) { free(CV_userdata); CV_userdata = NULL; *ier = -1; return; } N_VSetArrayPointer(atol, Vatol); *ier = CVodeSVtolerances(CV_cvodemem, *rtol, Vatol); N_VDestroy(Vatol); break; } /* On failure, exit */ if(*ier != CV_SUCCESS) { free(CV_userdata); CV_userdata = NULL; *ier = -1; return; } /* Grab optional output arrays and store them in global variables */ CV_iout = iout; CV_rout = rout; /* Store the unit roundoff in rout for user access */ CV_rout[5] = UNIT_ROUNDOFF; return; }
int run_rate_state_sim(std::vector<std::vector<realtype> > &results, RSParams ¶ms) { 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, ¶ms); if (check_flag(&flag, "CVodeSetUserData", 1)) return(1); flag = CVodeSetUserData(event_cvode, ¶ms); 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; }
int jmi_ode_cvode_new(jmi_ode_cvode_t** integrator_ptr, jmi_ode_solver_t* solver) { jmi_ode_cvode_t* integrator; jmi_ode_problem_t* problem = solver -> ode_problem; int flag = 0; void* cvode_mem; jmi_real_t* y; jmi_real_t* atol_nv; int i; integrator = (jmi_ode_cvode_t*)calloc(1,sizeof(jmi_ode_cvode_t)); if(!integrator){ jmi_log_node(problem->log, logError, "Error", "Failed to allocate the internal CVODE struct."); return -1; } /* DEFAULT VALUES NEEDS TO BE IMPROVED*/ integrator->lmm = CV_BDF; integrator->iter = CV_NEWTON; /* integrator->rtol = 1e-4; */ integrator->rtol = solver->rel_tol; if (problem->n_real_x > 0) { integrator->atol = N_VNew_Serial(problem->n_real_x); } else { integrator->atol = N_VNew_Serial(1); } atol_nv = NV_DATA_S(integrator->atol); if (problem->n_real_x > 0) { for (i = 0; i < problem->n_real_x; i++) { atol_nv[i] = 0.01*integrator->rtol*problem->nominal[i]; } }else{ atol_nv[0] = 0.01*integrator->rtol*1.0; } cvode_mem = CVodeCreate(integrator->lmm,integrator->iter); if(!cvode_mem){ jmi_log_node(problem->log, logError, "Error", "Failed to allocate the CVODE struct."); return -1; } /* Get the default values for the time and states */ if (problem->n_real_x > 0) { integrator->y_work = N_VNew_Serial(problem->n_real_x); y = NV_DATA_S(integrator->y_work); memcpy (y, problem->states, problem->n_real_x*sizeof(jmi_real_t)); }else{ integrator->y_work = N_VNew_Serial(1); y = NV_DATA_S(integrator->y_work); y[0] = 0.0; } flag = CVodeInit(cvode_mem, cv_rhs, problem->time, integrator->y_work); if(flag != 0) { jmi_log_node(problem->log, logError, "Error", "Failed to initialize CVODE. Returned with <error_flag: %d>", flag); return -1; } flag = CVodeSVtolerances(cvode_mem, integrator->rtol, integrator->atol); if(flag!=0){ jmi_log_node(problem->log, logError, "Error", "Failed to specify the tolerances. Returned with <error_flag: %d>", flag); return -1; } if (problem->n_real_x > 0) { flag = CVDense(cvode_mem, problem->n_real_x); }else{ flag = CVDense(cvode_mem, 1); } if(flag!=0){ jmi_log_node(problem->log, logError, "Error", "Failed to specify the linear solver. Returned with <error_flag: %d>", flag); return -1; } flag = CVodeSetUserData(cvode_mem, (void*)solver); if(flag!=0){ jmi_log_node(problem->log, logError, "Error", "Failed to specify the user data. Returned with <error_flag: %d>", flag); return -1; } if (problem->n_sw > 0){ flag = CVodeRootInit(cvode_mem, problem->n_sw, cv_root); if(flag!=0){ jmi_log_node(problem->log, logError, "Error", "Failed to specify the event indicator function. Returned with <error_flag: %d>", flag); return -1; } } flag = CVodeSetErrHandlerFn(cvode_mem, cv_err, (void*)solver); if(flag!=0){ jmi_log_node(problem->log, logError, "Error", "Failed to specify the error handling function. Returned with <error_flag: %d>", flag); return -1; } integrator->cvode_mem = cvode_mem; *integrator_ptr = integrator; return 0; }
void CVodesIntegrator::initialize(double t0, FuncEval& func) { m_neq = func.neq(); m_t0 = t0; m_time = t0; if (m_y) { N_VDestroy_Serial(m_y); // free solution vector if already allocated } m_y = N_VNew_Serial(static_cast<sd_size_t>(m_neq)); // allocate solution vector N_VConst(0.0, m_y); // check abs tolerance array size if (m_itol == CV_SV && m_nabs < m_neq) { throw CanteraError("CVodesIntegrator::initialize", "not enough absolute tolerance values specified."); } func.getState(NV_DATA_S(m_y)); if (m_cvode_mem) { CVodeFree(&m_cvode_mem); } //! Specify the method and the iteration type. Cantera Defaults: //! CV_BDF - Use BDF methods //! CV_NEWTON - use Newton's method m_cvode_mem = CVodeCreate(m_method, m_iter); if (!m_cvode_mem) { throw CanteraError("CVodesIntegrator::initialize", "CVodeCreate failed."); } int flag = CVodeInit(m_cvode_mem, cvodes_rhs, m_t0, m_y); if (flag != CV_SUCCESS) { if (flag == CV_MEM_FAIL) { throw CanteraError("CVodesIntegrator::initialize", "Memory allocation failed."); } else if (flag == CV_ILL_INPUT) { throw CanteraError("CVodesIntegrator::initialize", "Illegal value for CVodeInit input argument."); } else { throw CanteraError("CVodesIntegrator::initialize", "CVodeInit failed."); } } CVodeSetErrHandlerFn(m_cvode_mem, &cvodes_err, this); if (m_itol == CV_SV) { flag = CVodeSVtolerances(m_cvode_mem, m_reltol, m_abstol); } else { flag = CVodeSStolerances(m_cvode_mem, m_reltol, m_abstols); } if (flag != CV_SUCCESS) { if (flag == CV_MEM_FAIL) { throw CanteraError("CVodesIntegrator::initialize", "Memory allocation failed."); } else if (flag == CV_ILL_INPUT) { throw CanteraError("CVodesIntegrator::initialize", "Illegal value for CVodeInit input argument."); } else { throw CanteraError("CVodesIntegrator::initialize", "CVodeInit failed."); } } flag = CVodeSetUserData(m_cvode_mem, &func); if (flag != CV_SUCCESS) { throw CanteraError("CVodesIntegrator::initialize", "CVodeSetUserData failed."); } if (func.nparams() > 0) { sensInit(t0, func); flag = CVodeSetSensParams(m_cvode_mem, func.m_sens_params.data(), func.m_paramScales.data(), NULL); if (flag != CV_SUCCESS) { throw CanteraError("CVodesIntegrator::initialize", "CVodeSetSensParams failed."); } } applyOptions(); }