void FIDA_SETRIN(char key_name[], realtype *rval, int *ier) { if (!strncmp(key_name,"INIT_STEP",9)) *ier = IDASetInitStep(IDA_idamem, *rval); else if (!strncmp(key_name,"MAX_STEP",8)) *ier = IDASetMaxStep(IDA_idamem, *rval); else if (!strncmp(key_name,"STOP_TIME",9)) *ier = IDASetStopTime(IDA_idamem, *rval); else if (!strncmp(key_name,"NLCONV_COEF_IC",14)) *ier = IDASetNonlinConvCoefIC(IDA_idamem, *rval); else if (!strncmp(key_name,"NLCONV_COEF",11)) *ier = IDASetNonlinConvCoef(IDA_idamem, *rval); else if (!strncmp(key_name,"STEP_TOL_IC",11)) *ier = IDASetStepToleranceIC(IDA_idamem, *rval); else { *ier = -99; printf("FIDASETRIN: Unrecognized key.\n\n"); } }
void Ida::IDACore() { _idid = IDAReInit(_idaMem, _tCurrent, _CV_y,_CV_yp); _idid = IDASetStopTime(_idaMem, _tEnd); _idid = IDASetInitStep(_idaMem, 1e-12); if (_idid < 0) throw std::runtime_error("IDA::ReInit"); bool writeEventOutput = (_settings->getGlobalSettings()->getOutputPointType() == OPT_ALL); bool writeOutput = !(_settings->getGlobalSettings()->getOutputPointType() == OPT_NONE); while ((_solverStatus & ISolver::CONTINUE) && !_interrupt ) { _cv_rt = IDASolve(_idaMem, _tEnd, &_tCurrent, _CV_y, _CV_yp, IDA_ONE_STEP); _idid = IDAGetNumSteps(_idaMem, &_locStps); if (_idid != IDA_SUCCESS) throw std::runtime_error("IDAGetNumSteps failed. The ida mem pointer is NULL"); _idid =IDAGetLastStep(_idaMem, &_h); if (_idid != IDA_SUCCESS) throw std::runtime_error("IDAGetLastStep failed. The ida mem pointer is NULL"); //Check if there was at least one output-point within the last solver interval // -> Write output if true if (writeOutput) { writeIDAOutput(_tCurrent, _h, _locStps); } #ifdef RUNTIME_PROFILING MEASURETIME_REGION_DEFINE(idaStepCompletedHandler, "IDAStepCompleted"); if(MeasureTime::getInstance() != NULL) { MEASURETIME_START(measuredFunctionStartValues, idaStepCompletedHandler, "IDAStepCompleted"); } #endif //set completed step to system and check if terminate was called if(_continuous_system->stepCompleted(_tCurrent)) _solverStatus = DONE; #ifdef RUNTIME_PROFILING if(MeasureTime::getInstance() != NULL) { MEASURETIME_END(measuredFunctionStartValues, measuredFunctionEndValues, (*measureTimeFunctionsArray)[5], idaStepCompletedHandler); } #endif // Perform state selection bool state_selection = stateSelection(); if (state_selection) _continuous_system->getContinuousStates(_y); _zeroFound = false; // Check if step was successful if (check_flag(&_cv_rt, "IDA", 1)) { _solverStatus = ISolver::SOLVERERROR; break; } // A root was found if ((_cv_rt == IDA_ROOT_RETURN) && !isInterrupted()) { // IDA is setting _tCurrent to the time where the first event occurred double _abs = fabs(_tLastEvent - _tCurrent); _zeroFound = true; if ((_abs < 1e-3) && _event_n == 0) { _tLastEvent = _tCurrent; _event_n++; } else if ((_abs < 1e-3) && (_event_n >= 1 && _event_n < 500)) { _event_n++; } else if ((_abs >= 1e-3)) { //restart event counter _tLastEvent = _tCurrent; _event_n = 0; } else throw std::runtime_error("Number of events exceeded in time interval " + to_string(_abs) + " at time " + to_string(_tCurrent)); // IDA has interpolated the states at time 'tCurrent' _time_system->setTime(_tCurrent); // To get steep steps in the result file, two value points (P1 and P2) must be added // // Y | (P2) X........... // | : // | : // |........X (P1) // |----------------------------------> // | ^ t // _tCurrent // Write the values of (P1) if (writeEventOutput) { if(_dimAE>0) { _continuous_system->evaluateDAE(IContinuous::CONTINUOUS); } else { _continuous_system->evaluateAll(IContinuous::CONTINUOUS); } writeToFile(0, _tCurrent, _h); } _idid = IDAGetRootInfo(_idaMem, _zeroSign); for (int i = 0; i < _dimZeroFunc; i++) _events[i] = bool(_zeroSign[i]); if (_mixed_system->handleSystemEvents(_events)) { // State variables were reinitialized, thus we have to give these values to the ida-solver // Take care about the memory regions, _z is the same like _CV_y _continuous_system->getContinuousStates(_y); if(_dimAE>0) { _mixed_system->getAlgebraicDAEVars(_y+_dimStates); _continuous_system->getRHS(_yp); } calcFunction(_tCurrent, NV_DATA_S(_CV_y), NV_DATA_S(_CV_yp),_dae_res); } } if ((_zeroFound || state_selection)&& !isInterrupted()) { // Write the values of (P2) if (writeEventOutput) { // If we want to write the event-results, we should evaluate the whole system again if(_dimAE>0) { _continuous_system->evaluateDAE(IContinuous::CONTINUOUS); } else { _continuous_system->evaluateAll(IContinuous::CONTINUOUS); } writeToFile(0, _tCurrent, _h); } _idid = IDAReInit(_idaMem, _tCurrent, _CV_y,_CV_yp); if (_idid < 0) throw std::runtime_error("IDA::ReInit()"); // Der Eventzeitpunkt kann auf der Endzeit liegen (Time-Events). In diesem Fall wird der Solver beendet, da IDA sonst eine interne Warnung schmeißt if (_tCurrent == _tEnd) _cv_rt = IDA_TSTOP_RETURN; } // Zähler für die Anzahl der ausgegebenen Schritte erhöhen ++_outStps; _tLastSuccess = _tCurrent; if (_cv_rt == IDA_TSTOP_RETURN) { _time_system->setTime(_tEnd); _continuous_system->setContinuousStates(NV_DATA_S(_CV_y)); if(_dimAE>0) { _mixed_system->setAlgebraicDAEVars(NV_DATA_S(_CV_y)+_dimStates); _continuous_system->setStateDerivatives(NV_DATA_S(_CV_yp)); _continuous_system->evaluateDAE(IContinuous::CONTINUOUS); } else { _continuous_system->evaluateAll(IContinuous::CONTINUOUS); } if(writeOutput) writeToFile(0, _tEnd, _h); _accStps += _locStps; _solverStatus = DONE; } } }
CAMLprim value sundials_ml_ida_set_stop_time(value ida_solver, value tstop) { CAMLparam2(ida_solver, tstop); const int ret = IDASetStopTime(IDA_MEM(ida_solver), Double_val(tstop)); CAMLreturn(Val_int(ret)); }