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