Пример #1
0
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);
    }
}
Пример #3
0
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);
}
Пример #4
0
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);
  }
}
Пример #5
0
Файл: cvodes.c Проект: UCL/GMCMC
/**
 * 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;
}
Пример #6
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);
	}