示例#1
0
void FCV_SETIIN(char key_name[], long int *ival, int *ier)
{
  if (!strncmp(key_name,"MAX_ORD",7))
    *ier = CVodeSetMaxOrd(CV_cvodemem, (int) *ival);
  else if (!strncmp(key_name,"MAX_NSTEPS",10))
    *ier = CVodeSetMaxNumSteps(CV_cvodemem, (long int) *ival);
  else if (!strncmp(key_name,"MAX_ERRFAIL",11))
    *ier = CVodeSetMaxErrTestFails(CV_cvodemem, (int) *ival);
  else if (!strncmp(key_name,"MAX_NITERS",10))
    *ier = CVodeSetMaxNonlinIters(CV_cvodemem, (int) *ival);
  else if (!strncmp(key_name,"MAX_CONVFAIL",12))
    *ier = CVodeSetMaxConvFails(CV_cvodemem, (int) *ival);
  else if (!strncmp(key_name,"HNIL_WARNS",10))
    *ier = CVodeSetMaxHnilWarns(CV_cvodemem, (int) *ival);
  else if (!strncmp(key_name,"STAB_LIM",8))
    *ier = CVodeSetStabLimDet(CV_cvodemem, (booleantype) *ival);
  else {
    *ier = -99;
    fprintf(stderr, "FCVSETIIN: Unrecognized key.\n\n");
  }

}
示例#2
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);
  }
}
示例#3
0
void FCV_MALLOC(realtype *t0, realtype *y0, 
                int *meth, int *itmeth, int *iatol, 
                realtype *rtol, realtype *atol,
                int *optin, long int *iopt, realtype *ropt, 
                int *ier)
{
  int lmm, iter, itol;
  void *atolptr;

  atolptr = NULL;

  if(F2C_vec->ops->nvgetarraypointer == NULL ||
     F2C_vec->ops->nvsetarraypointer == NULL) {
    *ier = -1;
    printf("A required vector operation is not implemented.\n\n");
    return;
  }

  /* Save the data array in F2C_vec into data_F2C_vec and then 
     overwrite it with y0 */
  data_F2C_vec = N_VGetArrayPointer(F2C_vec);
  N_VSetArrayPointer(y0, F2C_vec);

  lmm = (*meth == 1) ? CV_ADAMS : CV_BDF;
  iter = (*itmeth == 1) ? CV_FUNCTIONAL : CV_NEWTON;
  switch (*iatol) {
  case 1:
    F2C_atolvec = NULL;
    itol = CV_SS; 
    atolptr = (void *) atol; 
    break;
  case 2:
    F2C_atolvec = N_VClone(F2C_vec);
    data_F2C_atolvec = N_VGetArrayPointer(F2C_atolvec);
    N_VSetArrayPointer(atol, F2C_atolvec);
    itol = CV_SV; 
    atolptr = (void *) F2C_atolvec; 
    break;
  case 3:
    F2C_atolvec = NULL;
    itol = CV_WF;
    break;
  }

  /* 
     Call CVodeCreate, CVodeSet*, and CVodeMalloc to initialize CVODE: 
     lmm     is the method specifier
     iter    is the iteration method specifier
     CVf     is the user's right-hand side function in y'=f(t,y)
     *t0     is the initial time
     F2C_vec is the initial dependent variable vector
     itol    specifies tolerance type
     rtol    is the scalar relative tolerance
     atolptr is the absolute tolerance pointer (to scalar or vector or function)

     A pointer to CVODE problem memory is createded and stored in CV_cvodemem. 
  */

  *ier = 0;

  CV_cvodemem = CVodeCreate(lmm, iter);

  if (CV_cvodemem == NULL) {
    *ier = -1;
    return;
  }

  if (*optin == 1) {
    CV_optin = TRUE;
    if (iopt[0] > 0)     CVodeSetMaxOrd(CV_cvodemem, (int)iopt[0]);
    if (iopt[1] > 0)     CVodeSetMaxNumSteps(CV_cvodemem, iopt[1]);
    if (iopt[2] > 0)     CVodeSetMaxHnilWarns(CV_cvodemem, (int)iopt[2]);
    if (iopt[13] > 0)    CVodeSetStabLimDet(CV_cvodemem, TRUE);
    if (iopt[21] > 0)    CVodeSetMaxErrTestFails(CV_cvodemem, (int)iopt[21]);
    if (iopt[22] > 0)    CVodeSetMaxNonlinIters(CV_cvodemem, (int)iopt[22]);
    if (iopt[23] > 0)    CVodeSetMaxConvFails(CV_cvodemem, (int)iopt[23]);
    if (ropt[0] != ZERO) CVodeSetInitStep(CV_cvodemem, ropt[0]);
    if (ropt[1] > ZERO)  CVodeSetMaxStep(CV_cvodemem, ropt[1]);
    if (ropt[2] > ZERO)  CVodeSetMinStep(CV_cvodemem, ropt[2]);
    if (ropt[7] != ZERO) CVodeSetStopTime(CV_cvodemem, ropt[7]);
    if (ropt[8] > ZERO)  CVodeSetNonlinConvCoef(CV_cvodemem, ropt[8]);
  } else {
    CV_optin = FALSE;
  }

  *ier = CVodeMalloc(CV_cvodemem, FCVf, *t0, F2C_vec, itol, *rtol, atolptr);

  /* reset data pointer into F2C_vec */
  N_VSetArrayPointer(data_F2C_vec, F2C_vec);

  /* destroy F2C_atolvec if allocated */
  if (F2C_atolvec != NULL) {
    N_VSetArrayPointer(data_F2C_atolvec, F2C_atolvec);
    N_VDestroy(F2C_atolvec);
  }

  if(*ier != CV_SUCCESS) {
    *ier = -1;
    return;
  }

  /* Store the unit roundoff in ropt for user access */
  ropt[9] = UNIT_ROUNDOFF;

  CV_iopt = iopt;
  CV_ropt = ropt;

  return;
}
示例#4
0
void FCV_REINIT(realtype *t0, realtype *y0, int *iatol, realtype *rtol,
                realtype *atol, int *optin, long int *iopt,
                realtype *ropt, int *ier)
{
  int itol;
  void *atolptr;

  atolptr = NULL;

  N_VSetArrayPointer(y0, F2C_vec);

  switch (*iatol) {
  case 1:
    itol = CV_SS; 
    atolptr = (void *) atol; 
    break;
  case 2:
    F2C_atolvec = N_VClone(F2C_vec);
    data_F2C_atolvec = N_VGetArrayPointer(F2C_atolvec);
    N_VSetArrayPointer(atol, F2C_atolvec);
    itol = CV_SV; 
    atolptr = (void *) F2C_atolvec; 
    break;
  case 3:
    itol = CV_WF;
  }

  /* 
     Call CVodeSet* and CVReInit to re-initialize CVODE: 
     CVf     is the user's right-hand side function in y'=f(t,y)
     t0      is the initial time
     F2C_vec is the initial dependent variable vector
     itol    specifies tolerance type
     rtol    is the scalar relative tolerance
     atolptr is the absolute tolerance pointer (to scalar or vector or function)
  */

  if (*optin == 1) {
    CV_optin = TRUE;
    if (iopt[0] > 0)     CVodeSetMaxOrd(CV_cvodemem, (int)iopt[0]);
    if (iopt[1] > 0)     CVodeSetMaxNumSteps(CV_cvodemem, iopt[1]);
    if (iopt[2] > 0)     CVodeSetMaxHnilWarns(CV_cvodemem, (int)iopt[2]);
    if (iopt[13] > 0)    CVodeSetStabLimDet(CV_cvodemem, TRUE);
    if (iopt[21] > 0)    CVodeSetMaxErrTestFails(CV_cvodemem, (int)iopt[21]);
    if (iopt[22] > 0)    CVodeSetMaxNonlinIters(CV_cvodemem, (int)iopt[22]);
    if (iopt[23] > 0)    CVodeSetMaxConvFails(CV_cvodemem, (int)iopt[23]);
    if (ropt[0] != ZERO) CVodeSetInitStep(CV_cvodemem, ropt[0]);
    if (ropt[1] > ZERO)  CVodeSetMaxStep(CV_cvodemem, ropt[1]);
    if (ropt[2] > ZERO)  CVodeSetMinStep(CV_cvodemem, ropt[2]);
    if (ropt[7] != ZERO) CVodeSetStopTime(CV_cvodemem, ropt[7]);
    if (ropt[8] > ZERO)  CVodeSetNonlinConvCoef(CV_cvodemem, ropt[8]);
  } else {
    CV_optin = FALSE;
  }

  *ier = CVodeReInit(CV_cvodemem, FCVf, *t0, F2C_vec, itol, *rtol, atolptr);

  /* reset data pointer into F2C_vec */
  N_VSetArrayPointer(data_F2C_vec, F2C_vec);

  /* destroy F2C_atolvec if allocated */
  if (F2C_atolvec != NULL) {
    N_VSetArrayPointer(data_F2C_atolvec, F2C_atolvec);
    N_VDestroy(F2C_atolvec);
  }

  if (*ier != CV_SUCCESS) {
    *ier = -1;
    return;
  }

  CV_iopt = iopt;
  CV_ropt = ropt;

  return;
}