void CVodesIntegrator::sensInit(double t0, FuncEval& func) { m_np = func.nparams(); size_t nv = func.neq(); m_sens_ok = false; doublereal* data; N_Vector y; y = N_VNew_Serial(static_cast<sd_size_t>(nv)); m_yS = N_VCloneVectorArray_Serial(static_cast<sd_size_t>(m_np), y); for (size_t n = 0; n < m_np; n++) { data = NV_DATA_S(m_yS[n]); for (size_t j = 0; j < nv; j++) { data[j] =0.0; } } int flag = CVodeSensInit(m_cvode_mem, static_cast<sd_size_t>(m_np), CV_STAGGERED, CVSensRhsFn(0), m_yS); if (flag != CV_SUCCESS) { throw CVodesErr("Error in CVodeSensMalloc"); } vector_fp atol(m_np, m_abstolsens); double rtol = m_reltolsens; flag = CVodeSensSStolerances(m_cvode_mem, rtol, atol.data()); }
void CVodesIntegrator::sensInit(double t0, FuncEval& func) { m_np = func.nparams(); m_sens_ok = false; N_Vector y = N_VNew_Serial(static_cast<sd_size_t>(func.neq())); m_yS = N_VCloneVectorArray_Serial(static_cast<sd_size_t>(m_np), y); for (size_t n = 0; n < m_np; n++) { N_VConst(0.0, m_yS[n]); } N_VDestroy_Serial(y); int flag = CVodeSensInit(m_cvode_mem, static_cast<sd_size_t>(m_np), CV_STAGGERED, CVSensRhsFn(0), m_yS); if (flag != CV_SUCCESS) { throw CanteraError("CVodesIntegrator::sensInit", "Error in CVodeSensInit"); } vector_fp atol(m_np); for (size_t n = 0; n < m_np; n++) { // This scaling factor is tuned so that reaction and species enthalpy // sensitivities can be computed simultaneously with the same abstol. atol[n] = m_abstolsens / func.m_paramScales[n]; } flag = CVodeSensSStolerances(m_cvode_mem, m_reltolsens, atol.data()); }
void CVodeInt::initialize(double t0, FuncEval& func) { m_neq = func.neq(); m_t0 = t0; if (m_y) { N_VFree(nv(m_y)); // free solution vector if already allocated } m_y = reinterpret_cast<void*>(N_VNew(m_neq, 0)); // allocate solution vector // check abs tolerance array size if (m_itol == 1 && m_nabs < m_neq) throw CVodeErr("not enough absolute tolerance values specified."); func.getInitialConditions(m_t0, m_neq, N_VDATA(nv(m_y))); // set options m_iopt[MXSTEP] = m_maxsteps; m_iopt[MAXORD] = m_maxord; m_ropt[HMAX] = m_hmax; if (m_cvode_mem) CVodeFree(m_cvode_mem); // pass a pointer to func in m_data m_data = (void*)&func; if (m_itol) { m_cvode_mem = CVodeMalloc(m_neq, cvode_rhs, m_t0, nv(m_y), m_method, m_iter, m_itol, &m_reltol, nv(m_abstol), m_data, NULL, TRUE, m_iopt, DATA_PTR(m_ropt), NULL); } else { m_cvode_mem = CVodeMalloc(m_neq, cvode_rhs, m_t0, nv(m_y), m_method, m_iter, m_itol, &m_reltol, &m_abstols, m_data, NULL, TRUE, m_iopt, DATA_PTR(m_ropt), NULL); } if (!m_cvode_mem) throw CVodeErr("CVodeMalloc failed."); if (m_type == DENSE + NOJAC) { CVDense(m_cvode_mem, NULL, NULL); } else if (m_type == DENSE + JAC) { CVDense(m_cvode_mem, cvode_jac, NULL); } else if (m_type == DIAG) { CVDiag(m_cvode_mem); } else if (m_type == GMRES) { CVSpgmr(m_cvode_mem, NONE, MODIFIED_GS, 0, 0.0, NULL, NULL, NULL); } else { throw CVodeErr("unsupported option"); } }
/** * Function called by cvodes to evaluate ydot given y. The CVODE integrator * allows passing in a void* pointer to access external data. This pointer * is cast to a pointer to a instance of class FuncEval. The equations to be * integrated should be specified by deriving a class from FuncEval that * evaluates the desired equations. * @ingroup odeGroup */ static int cvodes_rhs(realtype t, N_Vector y, N_Vector ydot, void* f_data) { try { FuncEval* f = (FuncEval*) f_data; f->eval(t, NV_DATA_S(y), NV_DATA_S(ydot), f->m_sens_params.data()); } catch (CanteraError& err) { std::cerr << err.what() << std::endl; return 1; // possibly recoverable error } catch (std::exception& err) { std::cerr << "cvodes_rhs: unhandled exception:" << std::endl; std::cerr << err.what() << std::endl; return -1; // unrecoverable error } catch (...) { std::cerr << "cvodes_rhs: unhandled exception of uknown type" << std::endl; return -1; // unrecoverable error } return 0; // successful evaluation }
void CVodesIntegrator::sensInit(double t0, FuncEval& func) { m_np = func.nparams(); long int nv = func.neq(); doublereal* data; int n, j; N_Vector y; y = N_VNew_Serial(nv); m_yS = N_VCloneVectorArray_Serial(m_np, y); for (n = 0; n < m_np; n++) { data = NV_DATA_S(m_yS[n]); for (j = 0; j < nv; j++) { data[j] =0.0; } } int flag; #if defined(SUNDIALS_VERSION_22) || defined(SUNDIALS_VERSION_23) flag = CVodeSensMalloc(m_cvode_mem, m_np, CV_STAGGERED, m_yS); if (flag != CV_SUCCESS) { throw CVodesErr("Error in CVodeSensMalloc"); } vector_fp atol(m_np, m_abstolsens); double rtol = m_reltolsens; flag = CVodeSetSensTolerances(m_cvode_mem, CV_SS, rtol, DATA_PTR(atol)); #elif defined(SUNDIALS_VERSION_24) flag = CVodeSensInit(m_cvode_mem, m_np, CV_STAGGERED, CVSensRhsFn (0), m_yS); if (flag != CV_SUCCESS) { throw CVodesErr("Error in CVodeSensMalloc"); } vector_fp atol(m_np, m_abstolsens); double rtol = m_reltolsens; flag = CVodeSensSStolerances(m_cvode_mem, rtol, DATA_PTR(atol)); #endif }
/** * Function called by cvodes to evaluate ydot given y. The CVODE * integrator allows passing in a void* pointer to access * external data. This pointer is cast to a pointer to a instance * of class FuncEval. The equations to be integrated should be * specified by deriving a class from FuncEval that evaluates the * desired equations. * @ingroup odeGroup */ static int cvodes_rhs(realtype t, N_Vector y, N_Vector ydot, void* f_data) { try { double* ydata = NV_DATA_S(y); double* ydotdata = NV_DATA_S(ydot); FuncData* d = (FuncData*)f_data; FuncEval* f = d->m_func; if (d->m_pars.size() == 0) { f->eval(t, ydata, ydotdata, NULL); } else { f->eval(t, ydata, ydotdata, d->m_pars.data()); } } catch (CanteraError& err) { std::cerr << err.what() << std::endl; return 1; // possibly recoverable error } catch (...) { std::cerr << "cvodes_rhs: unhandled exception" << std::endl; return -1; // unrecoverable error } return 0; // successful evaluation }
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(); }
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(); }
void CVodeInt::reinitialize(double t0, FuncEval& func) { m_t0 = t0; func.getInitialConditions(m_t0, m_neq, N_VDATA(nv(m_y))); // set options m_iopt[MXSTEP] = m_maxsteps; m_iopt[MAXORD] = m_maxord; m_ropt[HMAX] = m_hmax; //if (m_cvode_mem) CVodeFree(m_cvode_mem); // pass a pointer to func in m_data m_data = (void*)&func; int result; if (m_itol) { result = CVReInit(m_cvode_mem, cvode_rhs, m_t0, nv(m_y), m_method, m_iter, m_itol, &m_reltol, nv(m_abstol), m_data, NULL, TRUE, m_iopt, DATA_PTR(m_ropt), NULL); } else { result = CVReInit(m_cvode_mem, cvode_rhs, m_t0, nv(m_y), m_method, m_iter, m_itol, &m_reltol, &m_abstols, m_data, NULL, TRUE, m_iopt, DATA_PTR(m_ropt), NULL); } if (result != 0) throw CVodeErr("CVReInit failed."); if (m_type == DENSE + NOJAC) { CVDense(m_cvode_mem, NULL, NULL); } else if (m_type == DENSE + JAC) { CVDense(m_cvode_mem, cvode_jac, NULL); } else if (m_type == DIAG) { CVDiag(m_cvode_mem); } else if (m_type == GMRES) { CVSpgmr(m_cvode_mem, NONE, MODIFIED_GS, 0, 0.0, NULL, NULL, NULL); } else { throw CVodeErr("unsupported option"); } }
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); }
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); }
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 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(); }