From a8b6da1f6e332b52f566a293119da4de35627d59 Mon Sep 17 00:00:00 2001 From: Willi Braun Date: Sun, 19 Jan 2014 16:43:36 +0000 Subject: [PATCH] - added fix for stepSize calculation and output intervals #2539 git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@18688 f25d12d1-65f4-0310-ae8a-bbce733d8d8e --- .../c/simulation/simulation_runtime.cpp | 3 ++- .../c/simulation/solver/perform_simulation.c | 24 ++++++++----------- .../solver/simulation_inline_solver.h | 6 ++--- 3 files changed, 15 insertions(+), 18 deletions(-) diff --git a/SimulationRuntime/c/simulation/simulation_runtime.cpp b/SimulationRuntime/c/simulation/simulation_runtime.cpp index eaec5edae63..d833ad921f6 100644 --- a/SimulationRuntime/c/simulation/simulation_runtime.cpp +++ b/SimulationRuntime/c/simulation/simulation_runtime.cpp @@ -449,7 +449,8 @@ int startNonInteractiveSimulation(int argc, char**argv, DATA* data) } /* calc numStep */ - data->simulationInfo.numSteps = static_cast((data->simulationInfo.stopTime - data->simulationInfo.startTime)/data->simulationInfo.stepSize); + data->simulationInfo.numSteps = static_cast(round((data->simulationInfo.stopTime - data->simulationInfo.startTime)/data->simulationInfo.stepSize)); + infoStreamPrint(LOG_SOLVER, 0, "numberOfIntervals = %d", data->simulationInfo.numSteps); { /* Setup the clock */ enum omc_rt_clock_t clock = OMC_CLOCK_REALTIME; diff --git a/SimulationRuntime/c/simulation/solver/perform_simulation.c b/SimulationRuntime/c/simulation/solver/perform_simulation.c index 2fd3610e114..98a7c7f5852 100644 --- a/SimulationRuntime/c/simulation/solver/perform_simulation.c +++ b/SimulationRuntime/c/simulation/solver/perform_simulation.c @@ -89,11 +89,12 @@ int prefixedName_performSimulation(DATA* data, SOLVER_INFO* solverInfo) FILE *fmt = NULL; unsigned int stepNo=0; - double oldStepSize; SIMULATION_INFO *simInfo = &(data->simulationInfo); solverInfo->currentTime = simInfo->startTime; + + unsigned int __currStepNo = 0; if(measure_time_flag) { @@ -149,27 +150,25 @@ int prefixedName_performSimulation(DATA* data, SOLVER_INFO* solverInfo) rotateRingBuffer(data->simulationData, 1, (void**) data->localData); /***** Calculation next step size *****/ - /* Calculate new step size after an event */ if(solverInfo->didEventStep == 1) { - if((solverInfo->currentTime - solverInfo->laststep) + DBL_EPSILON > simInfo->stepSize) - solverInfo->currentStepSize = simInfo->stepSize; - else - solverInfo->currentStepSize = simInfo->stepSize - (solverInfo->currentTime - solverInfo->laststep); - infoStreamPrint(LOG_SOLVER, 0, "offset value for the next step: %.10f", (solverInfo->currentTime - solverInfo->laststep)); } else { - solverInfo->currentStepSize = simInfo->stepSize; + __currStepNo++; } + solverInfo->currentStepSize = (double)(__currStepNo*(simInfo->stopTime-simInfo->startTime))/(simInfo->numSteps) + simInfo->startTime - solverInfo->currentTime; - /* adjust final step? */ - if(solverInfo->currentTime + solverInfo->currentStepSize > simInfo->stopTime) { - solverInfo->currentStepSize = simInfo->stopTime - solverInfo->currentTime; + // if retry reduce stepsize + if(retry) + { + solverInfo->currentStepSize /= 2; } /***** End calculation next step size *****/ + + /* check for next time event */ checkForSampleEvent(data, solverInfo); infoStreamPrint(LOG_SOLVER, 1, "call solver from %g to %g (stepSize: %g)", solverInfo->currentTime, solverInfo->currentTime + solverInfo->currentStepSize, solverInfo->currentStepSize); @@ -239,7 +238,6 @@ int prefixedName_performSimulation(DATA* data, SOLVER_INFO* solverInfo) if(retry) { - simInfo->stepSize = oldStepSize; retry=0; } @@ -352,8 +350,6 @@ int prefixedName_performSimulation(DATA* data, SOLVER_INFO* solverInfo) { /* reduce step size by a half and try again */ solverInfo->laststep = solverInfo->currentTime - solverInfo->laststep; - oldStepSize = simInfo->stepSize; - simInfo->stepSize /= 2; /* restore old values and try another step with smaller step-size by dassl*/ restoreOldValues(data); diff --git a/SimulationRuntime/c/simulation/solver/simulation_inline_solver.h b/SimulationRuntime/c/simulation/solver/simulation_inline_solver.h index c167b1e6b8c..609d7819e97 100644 --- a/SimulationRuntime/c/simulation/solver/simulation_inline_solver.h +++ b/SimulationRuntime/c/simulation/solver/simulation_inline_solver.h @@ -69,13 +69,13 @@ extern const char* _omc_force_solver; #define _OMC_FORCE_SOLVER "inline-euler" #define _OMC_SOLVER_WORK_STATES_NDIMS 1 -#define begin_inline(void) { data->localData[0]->timeValue += stepSize; +#define begin_inline(void) { data->localData[0]->timeValue = data->localData[1]->timeValue + stepSize; #define end_inline(void) swap_double_arr(data->localData[0]->realVars,work_states[0]);} -#define inline_integrate(derx) { long _omc_index = &derx-(data->localData[0]->realVars + data->modelData.nStates); work_states[0][_omc_index] = data->localData[0]->realVars[_omc_index] + data->localData[0]->realVars[_omc_index + data->modelData.nStates] * stepSize; } +#define inline_integrate(derx) { long _omc_index = &derx-(data->localData[0]->realVars + data->modelData.nStates); work_states[0][_omc_index] = data->localData[1]->realVars[_omc_index] + data->localData[0]->realVars[_omc_index + data->modelData.nStates] * stepSize; } #define inline_integrate_array(sz,derx) { long _omc_size = sz; long _omc_index; \ for(_omc_index = &derx-(data->localData[0]->realVars + data->modelData.nStates); _omc_index < &derx-(data->localData[0]->realVars + data->modelData.nStates)+_omc_size; _omc_index++) \ - work_states[0][_omc_index] = data->localData[0]->realVars[_omc_index] + data->localData[0]->realVars[_omc_index + data->modelData.nStates] * stepSize; \ + work_states[0][_omc_index] = data->localData[1]->realVars[_omc_index] + data->localData[0]->realVars[_omc_index + data->modelData.nStates] * stepSize; \ } #elif defined(_OMC_INLINE_RK)