void FCV_LAPACKDENSE(int *neq, int *ier) { /* neq is the problem size */ *ier = CVLapackDense(CV_cvodemem, *neq); CV_ls = CV_LS_LAPACKDENSE; }
void CVodesIntegrator::applyOptions() { if (m_type == DENSE + NOJAC) { sd_size_t N = static_cast<sd_size_t>(m_neq); #if SUNDIALS_USE_LAPACK CVLapackDense(m_cvode_mem, N); #else CVDense(m_cvode_mem, N); #endif } 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) { sd_size_t N = static_cast<sd_size_t>(m_neq); long int nu = m_mupper; long int nl = m_mlower; #if SUNDIALS_USE_LAPACK CVLapackBand(m_cvode_mem, N, nu, nl); #else CVBand(m_cvode_mem, N, nu, nl); #endif } else { throw CanteraError("CVodesIntegrator::applyOptions", "unsupported option"); } if (m_maxord > 0) { CVodeSetMaxOrd(m_cvode_mem, m_maxord); } if (m_maxsteps > 0) { CVodeSetMaxNumSteps(m_cvode_mem, m_maxsteps); } if (m_hmax > 0) { CVodeSetMaxStep(m_cvode_mem, m_hmax); } if (m_hmin > 0) { CVodeSetMinStep(m_cvode_mem, m_hmin); } if (m_maxErrTestFails > 0) { CVodeSetMaxErrTestFails(m_cvode_mem, m_maxErrTestFails); } }
int CVLapackDenseB(void *cvode_mem, int which, int nB) { CVodeMem cv_mem; CVadjMem ca_mem; CVodeBMem cvB_mem; void *cvodeB_mem; CVDlsMemB cvdlsB_mem; int flag; /* Check if cvode_mem exists */ if (cvode_mem == NULL) { cvProcessError(NULL, CVDLS_MEM_NULL, "CVSLAPACK", "CVLapackDenseB", MSGD_CVMEM_NULL); return(CVDLS_MEM_NULL); } cv_mem = (CVodeMem) cvode_mem; /* Was ASA initialized? */ if (cv_mem->cv_adjMallocDone == FALSE) { cvProcessError(cv_mem, CVDLS_NO_ADJ, "CVSLAPACK", "CVLapackDenseB", MSGD_NO_ADJ); return(CVDLS_NO_ADJ); } ca_mem = cv_mem->cv_adj_mem; /* Check which */ if ( which >= ca_mem->ca_nbckpbs ) { cvProcessError(cv_mem, CVDLS_ILL_INPUT, "CVSLAPACK", "CVLapackDenseB", MSGCV_BAD_WHICH); return(CVDLS_ILL_INPUT); } /* Find the CVodeBMem entry in the linked list corresponding to which */ cvB_mem = ca_mem->cvB_mem; while (cvB_mem != NULL) { if ( which == cvB_mem->cv_index ) break; cvB_mem = cvB_mem->cv_next; } cvodeB_mem = (void *) (cvB_mem->cv_mem); /* Get memory for CVDlsMemRecB */ cvdlsB_mem = (CVDlsMemB) malloc(sizeof(struct CVDlsMemRecB)); if (cvdlsB_mem == NULL) { cvProcessError(cv_mem, CVDLS_MEM_FAIL, "CVSLAPACK", "CVLapackDenseB", MSGD_MEM_FAIL); return(CVDLS_MEM_FAIL); } /* set matrix type */ cvdlsB_mem->d_typeB = SUNDIALS_DENSE; /* initialize Jacobian function */ cvdlsB_mem->d_djacB = NULL; /* attach lmemB and lfreeB */ cvB_mem->cv_lmem = cvdlsB_mem; cvB_mem->cv_lfree = cvLapackDenseFreeB; flag = CVLapackDense(cvodeB_mem, nB); if (flag != CVDLS_SUCCESS) { free(cvdlsB_mem); cvdlsB_mem = NULL; } return(flag); }
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); } }
/** * Solves an initial value problem using CVODES to integrate over a system of * ODEs with optional forward sensitivity analysis. The initial conditions for * the system and for the sensitivity analysis are expected to be in the first * rows of simdata and sensitivities, respectively. * * @param [in] rhs the right-hand side of the system of ODEs * @param [in] num_timepoints the number of timepoints * @param [in] num_species the number of independent variables * @param [in] num_sens the number of parameters to compute sensitivities * for (set to zero to disable sensitivity * calculations) * @param [in] timepoints the timepoints at which data is to be returned * @param [in] params parameters * @param [in] sensi the indices of the parameters to compute the * sensitivities for (may be NULL to compute the * sensitivities for all parameters) * @param [in] options additional options for the integrator * @param [out] simdata contains the state values for each species at * each timepoint in column-major order. * @param [out] sensitivities sensitivities of each parameter in sensi * with respect to each independent variable. * The sensitivity of parameter j with respect to * variable k at timepoint i is stored at * (j * num_species + k) * lds + i. * May be NULL if sensitivities are not to be * calculated. * @param [in] lds leading dimension of simdata and sensitivities * * @return 0 on success, * GMCMC_ENOMEM if there was not enough memory to create the solver, * GMCMC_EINVAL if there was an invalid argument to the function, * GMCMC_ELINAL if the solution could not be found. */ int cvodes_solve(gmcmc_ode_rhs rhs, size_t num_timepoints, size_t num_species, size_t num_params, size_t num_sens, const double * timepoints, const double * params, const size_t * sensi, const cvodes_options * options, double * simdata, double * sensitivities, size_t lds) { int error; // Set vector of initial values N_Vector y = N_VNew_Serial((long int)num_species); for (size_t j = 0; j < num_species; j++) NV_Ith_S(y, j) = simdata[j * lds]; // Create CVODES object void * cvode_mem; if ((cvode_mem = CVodeCreate(CV_BDF, CV_NEWTON)) == NULL) GMCMC_ERROR("Failed to allocate ODE solver", GMCMC_ENOMEM); // Initialise CVODES solver if ((error = CVodeInit(cvode_mem, cvodes_rhs, timepoints[0], y)) != CV_SUCCESS) { CVodeFree(&cvode_mem); GMCMC_ERROR("Failed to initialise ODE solver", (error == CV_ILL_INPUT) ? GMCMC_EINVAL : GMCMC_ENOMEM); } // Set integration tolerances if ((error = CVodeSStolerances(cvode_mem, options->reltol, options->abstol)) != CV_SUCCESS) { CVodeFree(&cvode_mem); GMCMC_ERROR("Failed to set ODE solver integration tolerances", (error == CV_ILL_INPUT) ? GMCMC_EINVAL : GMCMC_ENOMEM); } // Create a copy of the parameters in case CVODES modifies them realtype * sens_params; if ((sens_params = malloc(num_params * sizeof(realtype))) == NULL) { CVodeFree(&cvode_mem); GMCMC_ERROR("Failed to allocate copy of parameter vector for sensitivity analysis", GMCMC_ENOMEM); } for (size_t i = 0; i < num_params; i++) sens_params[i] = (realtype)params[i]; // Set optional inputs cvodes_userdata userdata = { rhs, sens_params }; if ((error = CVodeSetUserData(cvode_mem, &userdata)) != CV_SUCCESS) { CVodeFree(&cvode_mem); free(sens_params); GMCMC_ERROR("Failed to set ODE solver user data", GMCMC_EINVAL); } // Attach linear solver module if ((error = CVLapackDense(cvode_mem, (int)num_species)) != CV_SUCCESS) { CVodeFree(&cvode_mem); free(sens_params); GMCMC_ERROR("Failed to attach ODE solver module", (error == CV_ILL_INPUT) ? GMCMC_EINVAL : GMCMC_ENOMEM); } N_Vector * yS = NULL; int * plist = NULL; if (num_sens > 0) { // Set sensitivity initial conditions yS = N_VCloneVectorArray_Serial((int)num_sens, y); for (size_t j = 0; j < num_sens; j++) { for (size_t i = 0; i < num_species; i++) NV_Ith_S(yS[j], i) = sensitivities[(j * num_species + i) * lds]; } // Activate sensitivity calculations // Use default finite differences if ((error = CVodeSensInit(cvode_mem, (int)num_sens, CV_SIMULTANEOUS, NULL, yS)) != CV_SUCCESS) { CVodeFree(&cvode_mem); free(sens_params); GMCMC_ERROR("Failed to activate ODE solver sensitivity calculations", (error == CV_ILL_INPUT) ? GMCMC_EINVAL : GMCMC_ENOMEM); } // Set sensitivity tolerances if ((error = CVodeSensEEtolerances(cvode_mem)) != CV_SUCCESS) { CVodeFree(&cvode_mem); free(sens_params); GMCMC_ERROR("Failed to set ODE solver sensitivity tolerances", (error == CV_ILL_INPUT) ? GMCMC_EINVAL : GMCMC_ENOMEM); } if (sensi != NULL) { if ((plist = malloc(num_sens * sizeof(int))) == NULL) { CVodeFree(&cvode_mem); free(sens_params); GMCMC_ERROR("Failed to allocate sensitivity parameter list", GMCMC_ENOMEM); } for (size_t i = 0; i < num_sens; i++) plist[i] = (int)sensi[i]; } // Set sensitivity analysis optional inputs if ((error = CVodeSetSensParams(cvode_mem, sens_params, NULL, plist)) != CV_SUCCESS) { CVodeFree(&cvode_mem); free(plist); free(sens_params); GMCMC_ERROR("Failed to set ODE solver sensitivity parameters", (error == CV_ILL_INPUT) ? GMCMC_EINVAL : GMCMC_ENOMEM); } } // Advance solution in time realtype tret; for (size_t i = 1; i < num_timepoints; i++) { if ((error = CVode(cvode_mem, timepoints[i], y, &tret, CV_NORMAL)) != CV_SUCCESS) { free(plist); free(sens_params); CVodeFree(&cvode_mem); GMCMC_ERROR("Failed to advance ODE solution", GMCMC_ELINAL); } for (size_t j = 0; j < num_species; j++) simdata[j * lds + i] = NV_Ith_S(y, j); // Extract the sensitivity solution if (yS != NULL) { if ((error = CVodeGetSens(cvode_mem, &tret, yS)) != CV_SUCCESS) { free(plist); free(sens_params); CVodeFree(&cvode_mem); GMCMC_ERROR("Failed to extract ODE sensitivity solution", GMCMC_ELINAL); } for (size_t j = 0; j < num_sens; j++) { for (size_t k = 0; k < num_species; k++) sensitivities[(j * num_species + k) * lds + i] = NV_Ith_S(yS[j], k); } } } N_VDestroy(y); if (yS != NULL) N_VDestroyVectorArray_Serial(yS, (int)num_sens); free(plist); free(sens_params); // Free solver memory CVodeFree(&cvode_mem); return 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); }