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 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 }
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(); }