From 90dce966dd0877e242248d2eb11efc0064dbd5c3 Mon Sep 17 00:00:00 2001 From: Willi Braun Date: Fri, 15 Feb 2013 02:53:50 +0000 Subject: [PATCH] - attempt to fix interactive mode - basic functions like start, pause, change parameter should work now - splitted solver_main therefore in smaller parts git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@15179 f25d12d1-65f4-0310-ae8a-bbce733d8d8e --- .../c/simulation/simulation_runtime.cpp | 43 +- .../c/simulation/simulation_runtime.h | 1 + SimulationRuntime/c/simulation/solver/dassl.c | 7 +- .../c/simulation/solver/solver_main.c | 436 +++++++++++------- .../c/simulation/solver/solver_main.h | 15 + .../interactive/omi_Calculation.cpp | 57 +-- SimulationRuntime/interactive/omi_Control.cpp | 64 +-- .../interactive/omi_ResultManager.cpp | 9 +- .../interactive/omi_ServiceInterface.cpp | 150 ++++-- .../interactive/omi_ServiceInterface.h | 6 +- 10 files changed, 492 insertions(+), 296 deletions(-) diff --git a/SimulationRuntime/c/simulation/simulation_runtime.cpp b/SimulationRuntime/c/simulation/simulation_runtime.cpp index 39afbd5a25c..4f8e416d524 100644 --- a/SimulationRuntime/c/simulation/simulation_runtime.cpp +++ b/SimulationRuntime/c/simulation/simulation_runtime.cpp @@ -498,6 +498,33 @@ int startNonInteractiveSimulation(int argc, char**argv, DATA* data) return retVal; } +/*! \fn initializeResultData(DATA* simData, int cpuTime) + * + * \param [ref] [simData] + * \param [int] [cpuTime] + * + * This function initializes result object to emit data. + */ +int initializeResultData(DATA* simData, string result_file_cstr, int cpuTime) +{ + int retVal = 0; + long maxSteps = 4 * simData->simulationInfo.numSteps; + if(isInteractiveSimulation() || sim_noemit || 0 == strcmp("empty", simData->simulationInfo.outputFormat)) { + sim_result = new simulation_result_empty(result_file_cstr.c_str(), maxSteps, simData, cpuTime); + } else if(0 == strcmp("csv", simData->simulationInfo.outputFormat)) { + sim_result = new simulation_result_csv(result_file_cstr.c_str(), maxSteps, simData, cpuTime); + } else if(0 == strcmp("mat", simData->simulationInfo.outputFormat)) { + sim_result = new simulation_result_mat(result_file_cstr.c_str(), simData->simulationInfo.startTime, simData->simulationInfo.stopTime, simData, cpuTime); + } else if(0 == strcmp("plt", simData->simulationInfo.outputFormat)) { + sim_result = new simulation_result_plt(result_file_cstr.c_str(), maxSteps, simData, cpuTime); + } else { + cerr << "Unknown output format: " << simData->simulationInfo.outputFormat << endl; + retVal = 1; + } + INFO2(LOG_SOLVER,"Allocated simulation result data storage for method '%s' and file='%s'", sim_result->result_type(), result_file_cstr.c_str()); + return retVal; +} + /** * Calls the solver which is selected in the parameter string "method" * This function is used for interactive and non-interactive simulation @@ -514,20 +541,8 @@ int callSolver(DATA* simData, string result_file_cstr, string init_initMethod, int retVal = -1; const char* outVars = (outputVariablesAtEnd.size() == 0) ? NULL : outputVariablesAtEnd.c_str(); - long maxSteps = 4 * simData->simulationInfo.numSteps; - if(isInteractiveSimulation() || sim_noemit || 0 == strcmp("empty", simData->simulationInfo.outputFormat)) { - sim_result = new simulation_result_empty(result_file_cstr.c_str(), maxSteps, simData, cpuTime); - } else if(0 == strcmp("csv", simData->simulationInfo.outputFormat)) { - sim_result = new simulation_result_csv(result_file_cstr.c_str(), maxSteps, simData, cpuTime); - } else if(0 == strcmp("mat", simData->simulationInfo.outputFormat)) { - sim_result = new simulation_result_mat(result_file_cstr.c_str(), simData->simulationInfo.startTime, simData->simulationInfo.stopTime, simData, cpuTime); - } else if(0 == strcmp("plt", simData->simulationInfo.outputFormat)) { - sim_result = new simulation_result_plt(result_file_cstr.c_str(), maxSteps, simData, cpuTime); - } else { - cerr << "Unknown output format: " << simData->simulationInfo.outputFormat << endl; - return 1; - } - INFO2(LOG_SOLVER,"Allocated simulation result data storage for method '%s' and file='%s'", sim_result->result_type(), result_file_cstr.c_str()); + if (initializeResultData(simData, result_file_cstr, cpuTime)) + return -1; if(simData->simulationInfo.solverMethod == std::string("")) { INFO(LOG_SOLVER, " | No solver is set, using dassl."); diff --git a/SimulationRuntime/c/simulation/simulation_runtime.h b/SimulationRuntime/c/simulation/simulation_runtime.h index d4448b6e954..f949273b607 100644 --- a/SimulationRuntime/c/simulation/simulation_runtime.h +++ b/SimulationRuntime/c/simulation/simulation_runtime.h @@ -65,6 +65,7 @@ extern simulation_result *sim_result; int callSolver(DATA* simData, std::string result_file_cstr, std::string init_initMethod, std::string init_optiMethod, std::string init_file, double init_time, int lambda_steps, std::string outputVariablesAtEnd, int cpuTime); +int initializeResultData(DATA* simData, std::string result_file_cstr, int cpuTime); #endif /* cplusplus */ diff --git a/SimulationRuntime/c/simulation/solver/dassl.c b/SimulationRuntime/c/simulation/solver/dassl.c index 402bc1709ec..d1bf5679b1a 100644 --- a/SimulationRuntime/c/simulation/solver/dassl.c +++ b/SimulationRuntime/c/simulation/solver/dassl.c @@ -123,6 +123,8 @@ dasrt_initial(DATA* simData, SOLVER_INFO* solverInfo, DASSL_DATA *dasslData){ int i; SIMULATION_INFO *simInfo = &(simData->simulationInfo); + dasslData->dasslMethod = 0; + for(i=0; i< DASSL_MAX;i++){ if(!strcmp((const char*)simInfo->solverMethod, dasslMethodStr[i])){ dasslData->dasslMethod = i; @@ -167,6 +169,8 @@ dasrt_initial(DATA* simData, SOLVER_INFO* solverInfo, DASSL_DATA *dasslData){ dasslData->dasslStatisticsTmp = (unsigned int*) calloc(numStatistics, sizeof(unsigned int)); ASSERT(dasslData->dasslStatisticsTmp,"out of memory"); + dasslData->idid = 0; + dasslData->sqrteps = sqrt(DBL_EPSILON); dasslData->ysave = (double*) malloc(simData->modelData.nStates*sizeof(double)); dasslData->delta_hh = (double*) malloc(simData->modelData.nStates*sizeof(double)); @@ -222,6 +226,7 @@ dasrt_deinitial(DASSL_DATA *dasslData){ free(dasslData->info); free(dasslData->dasslStatistics); free(dasslData->dasslStatisticsTmp); + free(dasslData); return 0; } @@ -256,6 +261,7 @@ int dasrt_step(DATA* simData, SOLVER_INFO* solverInfo) dasslData->idid = 0; } + /* Calculate time steps until TOUT is reached * (DASSL calculates beyond TOUT unless info[6] is set to 1!) */ tout = solverInfo->currentTime + solverInfo->currentStepSize; @@ -383,7 +389,6 @@ int dasrt_step(DATA* simData, SOLVER_INFO* solverInfo) } while(dasslData->idid == 1 || (dasslData->idid == -1 && solverInfo->currentTime <= simData->simulationInfo.stopTime)); - /* at the of one step evaluate the system again */ sData->timeValue = solverInfo->currentTime; if(ACTIVE_STREAM(LOG_DDASRT)) diff --git a/SimulationRuntime/c/simulation/solver/solver_main.c b/SimulationRuntime/c/simulation/solver/solver_main.c index c709cdeb299..da4b6622666 100644 --- a/SimulationRuntime/c/simulation/solver/solver_main.c +++ b/SimulationRuntime/c/simulation/solver/solver_main.c @@ -76,9 +76,9 @@ static int radauIIA_step(DATA* data, SOLVER_INFO* solverInfo); static void checkTermination(DATA* data); static void writeOutputVars(char* names, DATA* data); -int solver_main_step(int flag, DATA* data, SOLVER_INFO* solverInfo) +int solver_main_step(DATA* data, SOLVER_INFO* solverInfo) { - switch(flag) + switch(solverInfo->solverMethod) { case 2: return rungekutta_step(data, solverInfo); @@ -101,114 +101,179 @@ int solver_main_step(int flag, DATA* data, SOLVER_INFO* solverInfo) return 1; } -/*! \fn solver_main +/*! \fn initializeSolverData(DATA* data, SOLVER_INFO* solverInfo) + * + * \param [ref] [data] + * \param [ref] [solverInfo] * - * The main function for a solver with synchronous event handling - * flag 1=explicit euler - * 2=rungekutta - * 3=dassl - * 4=inline - * 5=free + * This function initializes solverInfo. */ -int solver_main(DATA* data, const char* init_initMethod, - const char* init_optiMethod, const char* init_file, double init_time, - int lambda_steps, int flag, const char* outputVariablesAtEnd) +int initializeSolverData(DATA* data, SOLVER_INFO* solverInfo) { + int retValue = 0; int i; - unsigned int ui; - SOLVER_INFO solverInfo; SIMULATION_INFO *simInfo = &(data->simulationInfo); SIMULATION_DATA *sData = data->localData[0]; - int retValIntegrator = 0; - int retVal = 0; - - FILE *fmt = NULL; - unsigned int stepNo = 0; - /* initial solverInfo */ - solverInfo.currentTime = simInfo->startTime; - solverInfo.currentStepSize = simInfo->stepSize; - solverInfo.laststep = 0; - solverInfo.offset = 0; - solverInfo.solverRootFinding = 0; - solverInfo.eventLst = allocList(sizeof(long)); - solverInfo.didEventStep = 0; - solverInfo.stateEvents = 0; - solverInfo.sampleEvents = 0; - - copyStartValuestoInitValues(data); - - /* read input vars */ - input_function(data); - - sData->timeValue = simInfo->startTime; - - /* instance all external Objects */ - callExternalObjectConstructors(data); - - /* allocate memory for state selection */ - initializeStateSetJacobians(data); - - if(flag == 2) + solverInfo->currentTime = simInfo->startTime; + solverInfo->currentStepSize = simInfo->stepSize; + solverInfo->laststep = 0; + solverInfo->offset = 0; + solverInfo->solverRootFinding = 0; + solverInfo->eventLst = allocList(sizeof(long)); + solverInfo->didEventStep = 0; + solverInfo->stateEvents = 0; + solverInfo->sampleEvents = 0; + + if(solverInfo->solverMethod == 2) { /* Allocate RK work arrays */ - RK4 rungeData; - rungeData.work_states_ndims = rungekutta_s; - rungeData.work_states = (double**) malloc((rungeData.work_states_ndims + 1) * sizeof(double*)); - for(i = 0; i < rungeData.work_states_ndims + 1; i++) - rungeData.work_states[i] = (double*) calloc(data->modelData.nStates, sizeof(double)); - solverInfo.solverData = &rungeData; + RK4* rungeData = (RK4*) malloc(sizeof(RK4)); + rungeData->work_states_ndims = rungekutta_s; + rungeData->work_states = (double**) malloc((rungeData->work_states_ndims + 1) * sizeof(double*)); + for(i = 0; i < rungeData->work_states_ndims + 1; i++) + rungeData->work_states[i] = (double*) calloc(data->modelData.nStates, sizeof(double)); + solverInfo->solverData = rungeData; } - else if(flag == 3) + else if(solverInfo->solverMethod == 3) { /* Initial DASSL solver */ - DASSL_DATA dasslData = {0}; + DASSL_DATA* dasslData = (DASSL_DATA*) malloc(sizeof(DASSL_DATA)); INFO(LOG_SOLVER, "Initializing DASSL"); - dasrt_initial(data, &solverInfo, &dasslData); - solverInfo.solverData = &dasslData; + retValue = dasrt_initial(data, solverInfo, dasslData); + solverInfo->solverData = dasslData; } - else if(flag == 4) + else if(solverInfo->solverMethod == 4) { /* Enable inlining solvers */ work_states = (double**) malloc(inline_work_states_ndims * sizeof(double*)); for(i = 0; i < inline_work_states_ndims; i++) work_states[i] = (double*) calloc(data->modelData.nVariablesReal, sizeof(double)); } -#ifdef PATHCONSTRAINTS - else if(flag == 5) + #ifdef PATHCONSTRAINTS + else if(solverInfo->solverMethod == 5) { int neqns = -1; /* Allocate work array for optimization*/ pathConstraints(data, NULL, &neqns); /* allocateDaeIpopt(data,neqns); */ } -#endif - else if (flag == 6) + #endif + else if (solverInfo->solverMethod == 6) { -#ifdef WITH_SUNDIALS + #ifdef WITH_SUNDIALS /* Allocate Radau IIA work arrays */ - allocateRadauIIA(&rData, data, &solverInfo); + allocateRadauIIA(&rData, data, solverInfo); allocateKinsol(&kData,(void*)&rData); -#else - return -1; -#endif + #else + retValue = -1; + #endif } - /* Calculate initial values from updateBoundStartValues() - * saveall() value as pre values */ if(measure_time_flag) { rt_accumulate(SIM_TIMER_PREINIT); rt_tick(SIM_TIMER_INIT); } + return retValue; +} + +/*! \fn freeSolver(DATA* data, SOLVER_INFO* solverInfo) + * + * \param [ref] [data] + * \param [ref] [solverInfo] + * + * This function frees solverInfo. + */ +int freeSolverData(DATA* data, SOLVER_INFO* solverInfo) +{ + int retValue = 0; + int i; + + /* deintialize solver related workspace */ + if(solverInfo->solverMethod == 2) + { + /* free RK work arrays */ + for(i = 0; i < ((RK4*)(solverInfo->solverData))->work_states_ndims + 1; i++) + free(((RK4*)(solverInfo->solverData))->work_states[i]); + free(((RK4*)(solverInfo->solverData))->work_states); + free((RK4*)solverInfo->solverData); + } + else if(solverInfo->solverMethod == 3) + { + /* De-Initial DASSL solver */ + dasrt_deinitial(solverInfo->solverData); + } + else if(solverInfo->solverMethod == 4) + { + /* De-Initial inline solver */ + for(i = 0; i < inline_work_states_ndims; i++) + free(work_states[i]); + free(work_states); + } + else if(solverInfo->solverMethod == 6) + { + #ifdef WITH_SUNDIALS + /* free work arrays */ + freeRadauIIA(&rData); + freeKinsol(&kData); + #endif + } + else + { + /* free other solver memory */ + } + + /* free stateset data */ + freeStateSetData(data); + + return retValue; +} + + +/*! \fn initializeModel(DATA* data, const char* init_initMethod, + * const char* init_optiMethod, const char* init_file, double init_time, + * int lambda_steps) + * + * \param [ref] [data] + * \param [in] [pInitMethod] user defined initialization method + * \param [in] [pOptiMethod] user defined optimization method + * \param [in] [pInitFile] extra argument for initialization-method "file" + * \param [in] [initTime] extra argument for initialization-method "file" + * \param [in] [lambda_steps] ??? + * + * This function starts the initialization process of the model . + */ +int initializeModel(DATA* data, const char* init_initMethod, + const char* init_optiMethod, const char* init_file, double init_time, + int lambda_steps) +{ + int retValue = 0; + + SIMULATION_INFO *simInfo = &(data->simulationInfo); + + copyStartValuestoInitValues(data); + + /* read input vars */ + input_function(data); + + data->localData[0]->timeValue = simInfo->startTime; + + /* instance all external Objects */ + callExternalObjectConstructors(data); + + /* allocate memory for state selection */ + initializeStateSetJacobians(data); + + if(initialization(data, init_initMethod, init_optiMethod, init_file, init_time, lambda_steps)) { WARNING(LOG_STDOUT, "Error in initialization. Storing results and exiting.\nUse -lv=LOG_INIT for more information."); simInfo->stopTime = simInfo->startTime; - retVal = -1; + retValue = -1; } /* adrpo: write the parameter data in the file once again after bound parameters and initialization! */ @@ -236,14 +301,30 @@ int solver_main(DATA* data, const char* init_initMethod, if(measure_time_flag) rt_accumulate( SIM_TIMER_INIT); - if(data->localData[0]->timeValue >= simInfo->stopTime) - { - INFO(LOG_SOLVER,"Simulation done!"); - solverInfo.currentTime = simInfo->stopTime; - } + return retValue; +} - INFO(LOG_SOLVER, "Performed initial value calculation."); - INFO2(LOG_SOLVER, "Start numerical solver from %g to %g", simInfo->startTime, simInfo->stopTime); + +/*! \fn performSimulation(DATA* data, SOLVER_INFO* solverInfo) + * + * \param [ref] [data] + * \param [ref] [solverInfo] + * + * This function performs the simulation controlled by solverInfo. + */ +int performSimulation(DATA* data, SOLVER_INFO* solverInfo) +{ + + int retValIntegrator = 0; + int retValue = 0; + int i, ui; + + FILE *fmt = NULL; + unsigned int stepNo = 0; + + SIMULATION_INFO *simInfo = &(data->simulationInfo); + + solverInfo->currentTime = simInfo->startTime; if(measure_time_flag) { @@ -265,7 +346,7 @@ int solver_main(DATA* data, const char* init_initMethod, printAllVars(data, 0, LOG_DEBUG); /***** Start main simulation loop *****/ - while(solverInfo.currentTime < simInfo->stopTime) + while(solverInfo->currentTime < simInfo->stopTime) { if(measure_time_flag) { @@ -280,25 +361,25 @@ int solver_main(DATA* data, const char* init_initMethod, /***** Calculation next step size *****/ /* Calculate new step size after an event */ - if(solverInfo.didEventStep == 1) + if(solverInfo->didEventStep == 1) { - solverInfo.offset = solverInfo.currentTime - solverInfo.laststep; - if(solverInfo.offset + DBL_EPSILON > simInfo->stepSize) - solverInfo.offset = 0; - INFO1(LOG_SOLVER, "offset value for the next step: %.10f", solverInfo.offset); + solverInfo->offset = solverInfo->currentTime - solverInfo->laststep; + if(solverInfo->offset + DBL_EPSILON > simInfo->stepSize) + solverInfo->offset = 0; + INFO1(LOG_SOLVER, "offset value for the next step: %.10f", solverInfo->offset); } else - solverInfo.offset = 0; - solverInfo.currentStepSize = simInfo->stepSize - solverInfo.offset; + solverInfo->offset = 0; + solverInfo->currentStepSize = simInfo->stepSize - solverInfo->offset; /* adjust final step? */ - if(solverInfo.currentTime + solverInfo.currentStepSize > simInfo->stopTime) - solverInfo.currentStepSize = simInfo->stopTime - solverInfo.currentTime; + if(solverInfo->currentTime + solverInfo->currentStepSize > simInfo->stopTime) + solverInfo->currentStepSize = simInfo->stopTime - solverInfo->currentTime; /***** End calculation next step size *****/ /* check for next sample event */ - checkForSampleEvent(data, &solverInfo); - INFO3(LOG_SOLVER, "call solver from %g to %g (stepSize: %g)", solverInfo.currentTime, solverInfo.currentTime + solverInfo.currentStepSize, solverInfo.currentStepSize); + checkForSampleEvent(data, solverInfo); + INFO3(LOG_SOLVER, "call solver from %g to %g (stepSize: %g)", solverInfo->currentTime, solverInfo->currentTime + solverInfo->currentStepSize, solverInfo->currentStepSize); /* * integration step @@ -306,8 +387,8 @@ int solver_main(DATA* data, const char* init_initMethod, * update continuous system */ INDENT(LOG_SOLVER); - communicateStatus("Running", (solverInfo.currentTime-simInfo->startTime)/(simInfo->stopTime-simInfo->startTime)); - retValIntegrator = solver_main_step(flag, data, &solverInfo); + communicateStatus("Running", (solverInfo->currentTime-simInfo->startTime)/(simInfo->stopTime-simInfo->startTime)); + retValIntegrator = solver_main_step(data, solverInfo); updateContinuousSystem(data); saveZeroCrossings(data); RELEASE(LOG_SOLVER); @@ -316,20 +397,20 @@ int solver_main(DATA* data, const char* init_initMethod, if(measure_time_flag) rt_tick(SIM_TIMER_EVENT); - if(checkEvents(data, solverInfo.eventLst, &(solverInfo.currentTime), &solverInfo)) + if(checkEvents(data, solverInfo->eventLst, &(solverInfo->currentTime), solverInfo)) { - INFO1(LOG_EVENTS, "event handling at time %g", solverInfo.currentTime); + INFO1(LOG_EVENTS, "event handling at time %g", solverInfo->currentTime); INDENT(LOG_EVENTS); - handleEvents(data, solverInfo.eventLst, &(solverInfo.currentTime), &solverInfo); + handleEvents(data, solverInfo->eventLst, &(solverInfo->currentTime), solverInfo); RELEASE(LOG_EVENTS); - solverInfo.didEventStep = 1; + solverInfo->didEventStep = 1; overwriteOldSimulationData(data); } else { - solverInfo.laststep = solverInfo.currentTime; - solverInfo.didEventStep = 0; + solverInfo->laststep = solverInfo->currentTime; + solverInfo->didEventStep = 0; } if(measure_time_flag) rt_accumulate(SIM_TIMER_EVENT); @@ -341,7 +422,7 @@ int solver_main(DATA* data, const char* init_initMethod, if(stateSelection(data, 1)) { /* if new set is calculated reinit the solver */ - solverInfo.didEventStep = 1; + solverInfo->didEventStep = 1; overwriteOldSimulationData(data); } @@ -389,10 +470,10 @@ int solver_main(DATA* data, const char* init_initMethod, /***** end of Emit this time step *****/ /* save dassl stats before reset */ - if(solverInfo.didEventStep == 1 && flag == 3) + if(solverInfo->didEventStep == 1 && solverInfo->solverMethod == 3) { for(ui = 0; ui < numStatistics; ui++) - ((DASSL_DATA*)solverInfo.solverData)->dasslStatistics[ui] += ((DASSL_DATA*)solverInfo.solverData)->dasslStatisticsTmp[ui]; + ((DASSL_DATA*)solverInfo->solverData)->dasslStatistics[ui] += ((DASSL_DATA*)solverInfo->solverData)->dasslStatisticsTmp[ui]; } /* Check for termination of terminate() or assert() */ @@ -405,7 +486,7 @@ int solver_main(DATA* data, const char* init_initMethod, if(!terminationAssert && terminationTerminate) { INFO2(LOG_STDOUT, "Simulation call terminate() at time %f\nMessage : %s", data->localData[0]->timeValue, TermMsg); - simInfo->stopTime = solverInfo.currentTime; + simInfo->stopTime = solverInfo->currentTime; } } @@ -427,36 +508,56 @@ int solver_main(DATA* data, const char* init_initMethod, if(data->simulationInfo.simulationSuccess) { - retVal = -1; - INFO1(LOG_STDOUT, "model terminate | Simulation terminated at time %g", solverInfo.currentTime); + retValue = -1; + INFO1(LOG_STDOUT, "model terminate | Simulation terminated at time %g", solverInfo->currentTime); } else if(retValIntegrator) { - retVal = -1 + retValIntegrator; - INFO1(LOG_STDOUT, "model terminate | Integrator failed. | Simulation terminated at time %g", solverInfo.currentTime); + retValue = -1 + retValIntegrator; + INFO1(LOG_STDOUT, "model terminate | Integrator failed. | Simulation terminated at time %g", solverInfo->currentTime); } else if(check_nonlinear_solutions(data)) { - retVal = -2; - INFO1(LOG_STDOUT, "model terminate | non-linear system solver failed. | Simulation terminated at time %g", solverInfo.currentTime); + retValue = -2; + INFO1(LOG_STDOUT, "model terminate | non-linear system solver failed. | Simulation terminated at time %g", solverInfo->currentTime); } else if(check_linear_solutions(data)) { - retVal = -3; - INFO1(LOG_STDOUT, "model terminate | linear system solver failed. | Simulation terminated at time %g", solverInfo.currentTime); + retValue = -3; + INFO1(LOG_STDOUT, "model terminate | linear system solver failed. | Simulation terminated at time %g", solverInfo->currentTime); } else if(check_mixed_solutions(data)) { - retVal = -3; - INFO1(LOG_STDOUT, "model terminate | mixed system solver failed. | Simulation terminated at time %g", solverInfo.currentTime); + retValue = -3; + INFO1(LOG_STDOUT, "model terminate | mixed system solver failed. | Simulation terminated at time %g", solverInfo->currentTime); } break; } } /* end while solver */ + if(fmt) + fclose(fmt); + + return retValue; +} + +/*! \fn finishSimulation(DATA* data, SOLVER_INFO* solverInfo) + * + * \param [ref] [data] + * \param [ref] [solverInfo] + * + * This function performs the last step + * and outputs some statistics, this this simulation terminal step. + */ +int finishSimulation(DATA* data, SOLVER_INFO* solverInfo, const char* outputVariablesAtEnd) +{ + int retValue = 0; + int ui; + + SIMULATION_INFO *simInfo = &(data->simulationInfo); /* Last step with terminal()=true */ - if(solverInfo.currentTime >= simInfo->stopTime) + if(solverInfo->currentTime >= simInfo->stopTime) { data->simulationInfo.terminal = 1; updateDiscreteSystem(data); @@ -474,7 +575,7 @@ int solver_main(DATA* data, const char* init_initMethod, if(ACTIVE_STREAM(LOG_STATS)) { rt_accumulate(SIM_TIMER_TOTAL); - + INFO(LOG_STATS, "### STATISTICS ###"); INFO(LOG_STATS, "timer"); @@ -487,76 +588,95 @@ int solver_main(DATA* data, const char* init_initMethod, INFO2(LOG_STATS, "%12gs [%5.1f%%] overhead", rt_accumulated(SIM_TIMER_OVERHEAD), rt_accumulated(SIM_TIMER_OVERHEAD)/rt_accumulated(SIM_TIMER_TOTAL)*100.0); INFO2(LOG_STATS, "%12gs [%5.1f%%] simulation", rt_accumulated(SIM_TIMER_TOTAL), rt_accumulated(SIM_TIMER_TOTAL)/rt_accumulated(SIM_TIMER_TOTAL)*100.0); RELEASE(LOG_STATS); - + INFO(LOG_STATS, "events"); INDENT(LOG_STATS); - INFO1(LOG_STATS, "%5ld state events", solverInfo.stateEvents); - INFO1(LOG_STATS, "%5ld sample events", solverInfo.sampleEvents); + INFO1(LOG_STATS, "%5ld state events", solverInfo->stateEvents); + INFO1(LOG_STATS, "%5ld sample events", solverInfo->sampleEvents); RELEASE(LOG_STATS); - + INFO(LOG_STATS, "solver"); INDENT(LOG_STATS); - if(flag == 3) /* dassl */ + if(solverInfo->solverMethod == 3) /* dassl */ { /* save dassl stats before print */ for(ui = 0; ui < numStatistics; ui++) - ((DASSL_DATA*)solverInfo.solverData)->dasslStatistics[ui] += ((DASSL_DATA*)solverInfo.solverData)->dasslStatisticsTmp[ui]; - - INFO1(LOG_STATS, "%5d steps taken", ((DASSL_DATA*)solverInfo.solverData)->dasslStatistics[0]); - INFO1(LOG_STATS, "%5d calls of functionODE", ((DASSL_DATA*)solverInfo.solverData)->dasslStatistics[1]); - INFO1(LOG_STATS, "%5d evaluations of jacobian", ((DASSL_DATA*)solverInfo.solverData)->dasslStatistics[2]); - INFO1(LOG_STATS, "%5d error test failures", ((DASSL_DATA*)solverInfo.solverData)->dasslStatistics[3]); - INFO1(LOG_STATS, "%5d convergence test failures", ((DASSL_DATA*)solverInfo.solverData)->dasslStatistics[4]); + ((DASSL_DATA*)solverInfo->solverData)->dasslStatistics[ui] += ((DASSL_DATA*)solverInfo->solverData)->dasslStatisticsTmp[ui]; + + INFO1(LOG_STATS, "%5d steps taken", ((DASSL_DATA*)solverInfo->solverData)->dasslStatistics[0]); + INFO1(LOG_STATS, "%5d calls of functionODE", ((DASSL_DATA*)solverInfo->solverData)->dasslStatistics[1]); + INFO1(LOG_STATS, "%5d evaluations of jacobian", ((DASSL_DATA*)solverInfo->solverData)->dasslStatistics[2]); + INFO1(LOG_STATS, "%5d error test failures", ((DASSL_DATA*)solverInfo->solverData)->dasslStatistics[3]); + INFO1(LOG_STATS, "%5d convergence test failures", ((DASSL_DATA*)solverInfo->solverData)->dasslStatistics[4]); } else { INFO(LOG_STATS, "sorry - no solver statistics available. [not yet implemented]"); } RELEASE(LOG_STATS); - + INFO(LOG_STATS, "### END STATISTICS ###"); - + rt_tick(SIM_TIMER_TOTAL); } +} - /* deintialize solver related workspace */ - if(flag == 2) - { - /* free RK work arrays */ - for(i = 0; i < ((RK4*)(solverInfo.solverData))->work_states_ndims + 1; i++) - free(((RK4*)(solverInfo.solverData))->work_states[i]); - free(((RK4*)(solverInfo.solverData))->work_states); - } - else if(flag == 3) - { - /* De-Initial DASSL solver */ - dasrt_deinitial(solverInfo.solverData); - } - else if(flag == 4) - { - /* De-Initial inline solver */ - for(i = 0; i < inline_work_states_ndims; i++) - free(work_states[i]); - free(work_states); - } - else if(flag == 6) - { -#ifdef WITH_SUNDIALS - /* free work arrays */ - freeRadauIIA(&rData); - freeKinsol(&kData); -#endif - } - else +/*! \fn solver_main + * + * \param [ref] [data] + * \param [in] [pInitMethod] user defined initialization method + * \param [in] [pOptiMethod] user defined optimization method + * \param [in] [pInitFile] extra argument for initialization-method "file" + * \param [in] [initTime] extra argument for initialization-method "file" + * \param [in] [lambda_steps] ??? + * \param [in] [flag] selects the ode solver + * \param [in] [outputVariablesAtEnd] ??? + * + * This is the main function of the solver it perform + * the simulation. + * + */ +int solver_main(DATA* data, const char* init_initMethod, + const char* init_optiMethod, const char* init_file, double init_time, + int lambda_steps, int flag, const char* outputVariablesAtEnd) +{ + int i; + unsigned int ui; + + int retVal = 0; + + SOLVER_INFO solverInfo; + SIMULATION_INFO *simInfo = &(data->simulationInfo); + + + solverInfo.solverMethod = flag; + + /* allocate SolverInfo memory */ + retVal = initializeSolverData(data, &solverInfo); + + /* initialize all parts of the model */ + if (!retVal) + retVal = initializeModel(data, init_initMethod, init_optiMethod, init_file, init_time, lambda_steps); + + + if(data->localData[0]->timeValue >= simInfo->stopTime) { - /* free other solver memory */ + INFO(LOG_SOLVER,"Simulation done!"); + solverInfo.currentTime = simInfo->stopTime; } - /* free stateset data */ - freeStateSetData(data); + INFO(LOG_SOLVER, "Performed initial value calculation."); + INFO2(LOG_SOLVER, "Start numerical solver from %g to %g", simInfo->startTime, simInfo->stopTime); - if(fmt) - fclose(fmt); + /* starts the simulation main loop */ + if (!retVal) + retVal = performSimulation(data, &solverInfo); + + /* terminate the simulation */ + finishSimulation(data, &solverInfo, outputVariablesAtEnd); + + /* free SolverInfo memory */ + freeSolverData(data, &solverInfo); return retVal; } diff --git a/SimulationRuntime/c/simulation/solver/solver_main.h b/SimulationRuntime/c/simulation/solver/solver_main.h index b5adc853c2f..68bdb09187e 100644 --- a/SimulationRuntime/c/simulation/solver/solver_main.h +++ b/SimulationRuntime/c/simulation/solver/solver_main.h @@ -48,6 +48,7 @@ typedef struct SOLVER_INFO double currentStepSize; double laststep; double offset; + int solverMethod; /* set by solver if an internal root finding method is activated */ modelica_boolean solverRootFinding; @@ -71,6 +72,20 @@ extern int solver_main(DATA* data, const char* init_initMethod, const char* init_optiMethod, const char* init_file, double init_time, int lambda_steps, int flag, const char* outputVariablesAtEnd); +/* Provide solver interface to interactive stuff */ +extern int initializeSolverData(DATA* data, SOLVER_INFO* solverInfo); +extern int freeSolverData(DATA* data, SOLVER_INFO* solverInfo); + +extern int freeSolverData(DATA* data, SOLVER_INFO* solverInfo); + +extern int initializeModel(DATA* data, const char* init_initMethod, + const char* init_optiMethod, const char* init_file, double init_time, + int lambda_steps); + +extern int performSimulation(DATA* data, SOLVER_INFO* solverInfo); + +extern int finishSimulation(DATA* data, SOLVER_INFO* solverInfo, const char* outputVariablesAtEnd); + #ifdef __cplusplus } #endif diff --git a/SimulationRuntime/interactive/omi_Calculation.cpp b/SimulationRuntime/interactive/omi_Calculation.cpp index 969470669fd..524c29adcd9 100644 --- a/SimulationRuntime/interactive/omi_Calculation.cpp +++ b/SimulationRuntime/interactive/omi_Calculation.cpp @@ -22,13 +22,10 @@ #include "omi_ServiceInterface.h" #include "omi_Control.h" #include "omi_Calculation.h" -#include "delay.h" using namespace std; -bool debugCalculation = true; //Set true to print out comments which describes the program flow to the console -bool forZero = true; //The first calculation must start from 0 to 0 (in OpenModelica the solver calculates from 0 - 2.220446049250313e-13) -bool* p_forZero = 0; //The first calculation must start from 0 to 0 (in OpenModelica the solver calculates from 0 - 2.220446049250313e-13) +bool debugCalculation = false; //Set true to print out comments which describes the program flow to the console bool calculationInterrupted = false; @@ -44,38 +41,29 @@ void printSSDCalculation(long, long, long); */ int calculate() { - DATA* globaldata = (DATA*) getGlobalData(); - int retVal = -1; double start = 0.0; double stop = 1.0; - double stepSizeORG = 1; double stepSize = 1; long outputSteps = 1; //unnecessary for interactive simulation double tolerance = 1e-4; string method; string outputFormat; - getSimulationStartData(&stepSizeORG, &outputSteps, &tolerance, &method, - &outputFormat); + + intializeSolverStartData(&stepSize, &outputSteps, &tolerance, &method, &outputFormat); //TODO 20100217 pv catch correct stepSize value for calculation loop if (debugCalculation) { cout << "Calculation:\tFunct.: calculate\tData 1: start: " << start - << " stop: " << stop << " stepSize: " << stepSizeORG + << " stop: " << stop << " stepSize: " << stepSize << " outputSteps: " << outputSteps << " method: " << method << " outputFormat: " << outputFormat; fflush( stdout); } - if (method == std::string("euler") || method == std::string("rungekutta") || method == std::string("dassl")) { - set_timeValue(start); - set_forceEmit(0); - } else { - set_lastEmittedTime(start); - set_forceEmit(0); - } + set_timeValue(start); + set_forceEmit(0); - initDelay(globaldata, start); while (!calculationInterrupted) { //TODO 20100210 pv Interrupt is not implemented yet @@ -83,10 +71,6 @@ int calculate() { if (simulationStatus == SimulationStatus::STOPPED) { // If the simulation should stop, unlock and break out of the loop. mutexSimulationStatus->Unlock(); - if (debugCalculation) { - cout << "Calculation:\tFunct.: calculate\tMessage: Simulation Stopped set forZero = true" << endl; fflush( stdout); - } - forZero = true; } if (simulationStatus == SimulationStatus::SHUTDOWN) { @@ -104,31 +88,28 @@ int calculate() { waitForResume->Wait(); //wait and reduce semaphore //TODO 20100210 pv testing rungekutter... - if (method == std::string("euler") || method == std::string("rungekutta") || method == std::string("dassl")) { - stop = get_timeValue() + stepSize; - start = get_timeValue(); - if (debugCalculation) { - cout << "Calculation:\tFunct.: calculate\tData 2: p_SimStepData_from_Calculation->forTimeStep: " << p_SimStepData_from_Calculation->forTimeStep << " ------" << endl; fflush( stdout); - cout << "Calculation:\tFunct.: calculate\tData 3: start " << start << " stop: " << stop << endl; fflush(stdout); - } - } else { - stop = get_lastEmittedTime() + stepSize; - start = get_lastEmittedTime(); + start = get_timeValue(); + stop = get_timeValue() + stepSize; + if (debugCalculation) { + cout << "Calculation:\tFunct.: calculate\tData 2: p_SimStepData_from_Calculation->forTimeStep: " << p_SimStepData_from_Calculation->forTimeStep << " ------" << endl; fflush( stdout); + cout << "Calculation:\tFunct.: calculate\tData 3: start " << start << " stop: " << stop << endl; fflush(stdout); } - retVal = callSolverFromOM(method, outputFormat, start, stop, stepSize, outputSteps, tolerance); + retVal = performSolverStepFromOM(start, stop, stepSize); if (retVal != 0) { cout << "Calculation:\tFunct.: calculate\tMessage: omi_Calculation: error occurred while calculating" << endl; fflush( stdout); return 1; } - stepSize = stepSizeORG; set_stepSize(stepSize); createSSDEntry(method); calculationInterrupted = false; + setResultData(p_SimStepData_from_Calculation); //ssd(tn) as parameter } + + deintializeSolverStartData(); //if (debugCalculation) cout << "Calculation:\tFunct.: calculate\tMessage: Calculation end: calculationInterrupted -> " @@ -145,9 +126,7 @@ void createSSDEntry(string method) { fillSimulationStepDataWithValuesFromGlobalData(method, p_SimStepData_from_Calculation); p_sdnMutex->Lock(); - long nStates = p_simdatanumbers->nStates; - long nAlgebraic = p_simdatanumbers->nAlgebraic; - long nParameters = p_simdatanumbers->nParameters; + p_sdnMutex->Unlock(); if (debugCalculation) //printSSDCalculation(nStates, nAlgebraic, nParameters); @@ -234,8 +213,6 @@ THREAD_RET_TYPE threadSimulationCalculation(THREAD_PARAM_TYPE lpParam) { long nParameters = p_simdatanumbers->nParameters; p_sdnMutex->Unlock(); - p_forZero = &forZero; - p_SimStepData_from_Calculation = &simStepData_from_Calculation; double *statesTMP2 = new double[nStates]; @@ -247,6 +224,8 @@ THREAD_RET_TYPE threadSimulationCalculation(THREAD_PARAM_TYPE lpParam) { p_SimStepData_from_Calculation->algebraics = algebraicsTMP2; p_SimStepData_from_Calculation->parameters = parametersTMP2; + + retValue = calculate(); if (debugCalculation) { diff --git a/SimulationRuntime/interactive/omi_Control.cpp b/SimulationRuntime/interactive/omi_Control.cpp index 79990492dfc..f4e2bf8230b 100644 --- a/SimulationRuntime/interactive/omi_Control.cpp +++ b/SimulationRuntime/interactive/omi_Control.cpp @@ -47,7 +47,7 @@ string control_client_ip = ""; int control_client_port = 0; int control_server_port = 0; -int debugLevelControl = 2; //Set the debug level higher zero to print out messages which describes the program flow to the console [0= debug off, 1= min-debug, 2= max-debug] +int debugLevelControl = 0; //Set the debug level higher zero to print out messages which describes the program flow to the console [0= debug off, 1= min-debug, 2= max-debug] bool shutDownSignal = false; bool error = false; string messageForClient; @@ -298,7 +298,6 @@ void reInitAll() { cout << "Control:\tFunct.: reInitAll\tData: globalData->timeValue: " << get_timeValue() << endl; fflush(stdout); } - *p_forZero = true; } /** @@ -317,8 +316,7 @@ void changeParameterValues(double changedSimulationTime, string parameter) { if (status.compare("start") == 0) pauseSimulation(); - SimStepData* p_ssdAtChangedSimulationTime = getResultDataForTime(get_stepSize(), - changedSimulationTime); + SimStepData* p_ssdAtChangedSimulationTime = getResultDataForTime(get_stepSize(), changedSimulationTime); if (debugLevelControl > 0) { cout << "Control:\tFunct.: changeParameterValues\tData: p_ssdAtChangedSimulationTime->forTimeStep: " << p_ssdAtChangedSimulationTime->forTimeStep << endl; fflush(stdout); @@ -327,9 +325,14 @@ void changeParameterValues(double changedSimulationTime, string parameter) { if (p_ssdAtChangedSimulationTime->forTimeStep != -1) { parseParameter(p_ssdAtChangedSimulationTime, parameter); + if (debugLevelControl > 0) + { + cout << "Control:\tFunct.: parseParameter " << endl; fflush(stdout); + } setGlobalSimulationValuesFromSimulationStepData(p_ssdAtChangedSimulationTime); - resetSRDFAfterChangetime(); //Resets the SRDF Array and the producer and consumer semaphores - setSimulationTimeReversed(get_stepSize() + changedSimulationTime); + + //resetSRDFAfterChangetime(); //Resets the SRDF Array and the producer and consumer semaphores + //setSimulationTimeReversed(get_stepSize() + changedSimulationTime); if (debugLevelControl > 0) { cout << "Control:\tFunct.: changeParameterValues\tData:globalData->lastEmittedTime: " << get_lastEmittedTime() << endl; fflush(stdout); @@ -463,10 +466,11 @@ void startSimulation() mutexSimulationStatus->Unlock(); status = "start"; - - cout << "Control:\tFunct.: startSimulation\tMessage: start done" << endl; fflush( stdout); + if (debugLevelControl > 0) + cout << "Control:\tFunct.: startSimulation\tMessage: start done" << endl; fflush( stdout); } else { - cout << "Control:\tFunct.: startSimulation\tMessage: already started" << endl; fflush( stdout); + if (debugLevelControl > 0) + cout << "Control:\tFunct.: startSimulation\tMessage: already started" << endl; fflush( stdout); } } @@ -495,42 +499,46 @@ void pauseSimulation() releaseMutexSSD(); status = "pause"; - cout << "Control:\tFunct.: pauseSimulation\tMessage: pause done" << endl; fflush( stdout); + if (debugLevelControl > 0) + cout << "Control:\tFunct.: pauseSimulation\tMessage: pause done" << endl; fflush( stdout); } else { - cout << "Control:\tFunct.: pauseSimulation\tMessage: already paused or stopped" << endl; fflush( stdout); + if (debugLevelControl > 0) + cout << "Control:\tFunct.: pauseSimulation\tMessage: already paused or stopped" << endl; fflush( stdout); } - - cout << "Control:\tFunct.: pauseSimulation\t[" << getMinTime_inSSD() << " - " << getMaxTime_inSSD() << "]" << endl; fflush( stdout); + if (debugLevelControl > 0) + cout << "Control:\tFunct.: pauseSimulation\t[" << getMinTime_inSSD() << " - " << getMaxTime_inSSD() << "]" << endl; fflush( stdout); } /** * Interrupts the simulation and reset all simulation data to initial state */ void stopSimulation(void) { - if (status.compare("stop") != 0) - { - pauseSimulation(); + if (status.compare("stop") != 0) + { + pauseSimulation(); - // Is this necessary anymore: pv yes, because the ssdArray must be synchronized - lockMutexSSD(); - denied_work_on_GD(); + // Is this necessary anymore: pv yes, because the ssdArray must be synchronized + lockMutexSSD(); + denied_work_on_GD(); - reInitAll(); + reInitAll(); - mutexSimulationStatus->Lock(); - simulationStatus = SimulationStatus::STOPPED; - mutexSimulationStatus->Unlock(); + mutexSimulationStatus->Lock(); + simulationStatus = SimulationStatus::STOPPED; + mutexSimulationStatus->Unlock(); - allow_work_on_GD(); - releaseMutexSSD(); + allow_work_on_GD(); + releaseMutexSSD(); - status = "stop"; + status = "stop"; - cout << "Control:\tFunct.: stopSimulation\tMessage: stop done" << endl; fflush(stdout); + if (debugLevelControl > 0) + cout << "Control:\tFunct.: stopSimulation\tMessage: stop done" << endl; fflush(stdout); } else { - cout << "Control:\tFunct.: stopSimulation\tMessage: already stopped" << endl; fflush(stdout); + if (debugLevelControl > 0) + cout << "Control:\tFunct.: stopSimulation\tMessage: already stopped" << endl; fflush(stdout); } } diff --git a/SimulationRuntime/interactive/omi_ResultManager.cpp b/SimulationRuntime/interactive/omi_ResultManager.cpp index 562abd7d4e5..01f97ebcd0b 100644 --- a/SimulationRuntime/interactive/omi_ResultManager.cpp +++ b/SimulationRuntime/interactive/omi_ResultManager.cpp @@ -59,7 +59,7 @@ SimStepData simulationStartSSD; SimStepData* p_simulationStartSSD; //***** SimStepData buffer ***** -SimStepData ssdArray[MAX_SSD] = { 0 }; +SimStepData ssdArray[MAX_SSD] = {{0}}; SimStepData* p_ssdArray_NextFreeSlot = 0; //Points on the next free slot @@ -232,7 +232,7 @@ bool setResultData(SimStepData* p_SimStepData_from_Calculation) { ssdMutex.Lock(); /******************************************************************** - * Entity has pas the synchronization sektion and can work on the SSD buffer + * Entity has pas the synchronization section and can work on the SSD buffer * Restrictions: if the simulation has been reseted the first time value must be VALID_TIME_AFTER_RESET * otherwise the result won't be added to the system */ @@ -240,7 +240,9 @@ bool setResultData(SimStepData* p_SimStepData_from_Calculation) { //block used by normal running simulation if(!simulationReset && !simulationChangetime){ addDataToSSD(p_SimStepData_from_Calculation); - //cout << "add time: " << p_SimStepData_from_Calculation->forTimeStep << endl; fflush(stdout); + if (debugResultManager > 0) { + cout << "add time: " << p_SimStepData_from_Calculation->forTimeStep << endl; fflush(stdout); + } }else{//block used once after simulation has been reseted or more if the next time to add into the ssd is not VALID_TIME_AFTER_RESET if(simulationReset){ if(p_SimStepData_from_Calculation->forTimeStep == VALID_TIME_AFTER_RESET || p_SimStepData_from_Calculation->forTimeStep == 0){ @@ -654,7 +656,6 @@ void popSRDF(SimStepData* p_SimResDataForw_from_Transfer) { bool compareDouble(double a, double b) { - cout << "fabs(a - b): " << fabs(a - b) << endl; return fabs(a - b) < EPSILON; } diff --git a/SimulationRuntime/interactive/omi_ServiceInterface.cpp b/SimulationRuntime/interactive/omi_ServiceInterface.cpp index 1ef602c59ed..b456d63c9dd 100644 --- a/SimulationRuntime/interactive/omi_ServiceInterface.cpp +++ b/SimulationRuntime/interactive/omi_ServiceInterface.cpp @@ -36,6 +36,7 @@ double global_stepSize = 0.0; // Global Data structure DATA* globalData; +SOLVER_INFO* solverInfo; /** * Initializes the service interface data @@ -70,14 +71,13 @@ long get_NStates(void) { long temp_val = globalData->modelData.nStates; gdMutex.Unlock(); - return temp_val; } long get_NAlgebraic(void) { gdMutex.Lock(); - long temp_val = globalData->modelData.nVariablesReal; + long temp_val = globalData->modelData.nVariablesReal-2*globalData->modelData.nStates; gdMutex.Unlock(); @@ -335,7 +335,9 @@ void set_timeValue(double new_timeValue) { void set_lastEmittedTime(double new_lastEmittedTime) { gdMutex.Lock(); - globalData->localData[1]->timeValue = new_lastEmittedTime; + // What's the propose of that??? + // One can't change things that were happen already!!! + cout << "set_lastEmittedTime not implemented!" << endl; gdMutex.Unlock(); } @@ -344,7 +346,7 @@ void set_lastEmittedTime(double new_lastEmittedTime) { double get_lastEmittedTime(void) { gdMutex.Lock(); - double temp_let = globalData->localData[1]->timeValue; + double temp_let = globalData->localData[0]->timeValue - solverInfo->currentStepSize; gdMutex.Unlock(); @@ -394,23 +396,21 @@ int get_forceEmit(void){ void setGlobalSimulationValuesFromSimulationStepData(SimStepData* p_SimStepData){ gdMutex.Lock(); - //TODO [20110319] pv workaround to fix dassl2 problem using globalData->lastEmittedTime -// if (method == std::string("euler") || method == std::string("rungekutta") -// || method == std::string("dassl")) { - globalData->localData[0]->timeValue = p_SimStepData->forTimeStep; //is the timeValue of this step -// } else { -// globalData->lastEmittedTime = p_SimStepData->forTimeStep; //is the lastEmittedTime of this step -// } - long nStates = get_NStates(); - long nAlgebraic = get_NAlgebraic(); - long nParameters = get_NParameters(); + /* + * With the currect implementation it's not possible + * to change the time. + */ + //globalData->localData[0]->timeValue = p_SimStepData->forTimeStep; + + long nStates = globalData->modelData.nStates; + long nParameters = globalData->modelData.nParametersReal; + /* For now permit only parameter and states changes, since + * changes of stateDerivates and algebraic variables are + * anyway not possible, they are calculated! + */ for (int i = 0; i < nStates; i++) { globalData->localData[0]->realVars[i] = p_SimStepData->states[i]; - globalData->localData[0]->realVars[nStates + i] = p_SimStepData->statesDerivatives[i]; - } - for (int i = 0; i < nAlgebraic; i++) { - globalData->localData[0]->realVars[2*nStates + i] = p_SimStepData->algebraics[i]; } for (int i = 0; i < nParameters; i++) { globalData->simulationInfo.realParameter[i] = p_SimStepData->parameters[i]; @@ -422,18 +422,11 @@ void fillSimulationStepDataWithValuesFromGlobalData(string method, SimStepData* gdMutex.Lock(); - long nStates = get_NStates(); - long nAlgebraic = get_NAlgebraic(); - long nParameters = get_NParameters(); + long nStates = globalData->modelData.nStates; + long nAlgebraic = globalData->modelData.nVariablesReal-2*globalData->modelData.nStates; + long nParameters = globalData->modelData.nParametersReal; - if (method == std::string("euler") || method == std::string("rungekutta") || method == std::string("dassl")) { - p_SimStepData->forTimeStep = globalData->localData[0]->timeValue; //is the lastEmittedTime of this step - } - /* - else { - p_SimStepData->forTimeStep = globalData->lastEmittedTime; //is the lastEmittedTime of this step - } - */ + p_SimStepData->forTimeStep = globalData->localData[0]->timeValue; //is the lastEmittedTime of this step for (int i = 0; i < nStates; i++) { p_SimStepData->states[i] = globalData->localData[0]->realVars[i]; @@ -460,9 +453,9 @@ void fillSimDataNames_AND_SimDataNamesFilter_WithValuesFromGlobalData( SimDataNames* p_simDataNames, SimDataNamesFilter* p_simDataNamesFilter) { gdMutex.Lock(); - long nStates = get_NStates(); - long nAlgebraic = get_NAlgebraic(); - long nParameters = get_NParameters(); + long nStates = globalData->modelData.nStates; + long nAlgebraic = globalData->modelData.nVariablesReal-2*globalData->modelData.nStates; + long nParameters = globalData->modelData.nParametersReal; int variablesNamesPos = 0; for (int i = 0; i < nStates; i++) { @@ -490,36 +483,91 @@ void fillSimDataNames_AND_SimDataNamesFilter_WithValuesFromGlobalData( * Calls the "read_input_xml(...)" function from "simulation_input.cpp" and stores the simulation start data into * a set of variables from "omi_Calculation.cpp" */ -void getSimulationStartData(double *stepSize, long *outputSteps, +int intializeSolverStartData(double *stepSize, long *outputSteps, double *tolerance, string* method, string* outputFormat){ - double start = 0.0; //unnecessary for interactive simulation - double stop = 1.0; //unnecessary for interactive simulation - string variableFilter; //unnecessary for interactive simulation - gdMutex.Lock(); + int retVal = -1; - MODEL_DATA* modelData = &globalData->modelData; SIMULATION_INFO* simInfo = &globalData->simulationInfo; - read_input_xml(argcTEMP, argvTEMP, modelData, simInfo); - callExternalObjectConstructors(globalData); + string result_file_cstr = string(globalData->modelData.modelFilePrefix) + string("_res.") + simInfo->outputFormat; + + retVal = initializeResultData(globalData, result_file_cstr, 0); + + solverInfo = (SOLVER_INFO*) malloc(sizeof(SOLVER_INFO)); + + + if(simInfo->solverMethod == std::string("rungekutta")) + { + solverInfo->solverMethod = 2; + } + else if(simInfo->solverMethod == std::string("dassl")) + { + solverInfo->solverMethod = 3; + } + /* as fallback and default euler solver is used */ + else + { + solverInfo->solverMethod = 1; + } + + *stepSize = simInfo->stepSize; + *outputSteps = simInfo->stepSize; + *tolerance = simInfo->tolerance; + *method = simInfo->solverMethod; + + + /* allocate SolverInfo memory */ + if (!retVal) + retVal = initializeSolverData(globalData, solverInfo); + + /* initialize all parts of the model */ + if (!retVal) + retVal = initializeModel(globalData, "", "", "", 0.0, 0); + gdMutex.Unlock(); + + return retVal; } + +/* + * Calls the "read_input_xml(...)" function from "simulation_input.cpp" and stores the simulation start data into + * a set of variables from "omi_Calculation.cpp" + */ +void deintializeSolverStartData(void){ + + gdMutex.Lock(); + + /* terminate the simulation */ + finishSimulation(globalData, solverInfo, ""); + + /* free SolverInfo memory */ + freeSolverData(globalData, solverInfo); + + + gdMutex.Unlock(); +} //************ END Global Data Value Request and Manipulation ************ /* * Calls the solver which is selected in the parameter string "method" */ -int callSolverFromOM(string method, string outputFormat, double start, double stop, double stepSize, - long outputSteps, double tolerance) { +int performSolverStepFromOM(double start, double stop, double stepSize) { int retVal = -1; gdMutex.Lock(); - retVal = callSolver(globalData, "", "", "", "", 0, 0, "", 0); + + SIMULATION_INFO* simInfo = &globalData->simulationInfo; + simInfo->stepSize = stepSize; + simInfo->startTime = start; + simInfo->stopTime = stop; + + /* starts the simulation main loop */ + retVal = performSimulation(globalData, solverInfo); gdMutex.Unlock(); return retVal; @@ -602,28 +650,32 @@ void printGlobalData(void) { cout << "lastEmittedTime: " << globalData->localData[1]->timeValue << " --------------------" << endl; fflush(stdout); cout << "timeValue: " << globalData->localData[0]->timeValue << " --------------------" << endl; fflush(stdout); - if (get_NStates() > 0) + long nStates = globalData->modelData.nStates; + long nAlgebraic = globalData->modelData.nVariablesReal-2*globalData->modelData.nStates; + long nParameters = globalData->modelData.nParametersReal; + + if (nStates > 0) { cout << "---States---" << endl; fflush(stdout); - for (int t = 0; t < get_NStates(); t++) + for (int t = 0; t < nStates; t++) { cout << t << ": " << get_StateName(t) << ": " << get_StateValue(t) << endl; fflush(stdout); } } - if (get_NAlgebraic()> 0) + if (nAlgebraic > 0) { cout << "---Algebraics---" << endl; fflush(stdout); - for (int t = 0; t < get_NAlgebraic(); t++) + for (int t = 0; t < nAlgebraic; t++) { cout << t << ": " << get_AlgebraicName(t) << ": " << get_AlgebraicValue(t) << endl; fflush(stdout); } } - if (get_NParameters() > 0) + if (nParameters > 0) { cout << "---Parmeters--- " << endl; fflush(stdout); - for (int t = 0; t < get_NParameters(); t++) + for (int t = 0; t < nParameters; t++) { cout << t << ": " << get_ParameterName(t) << ": " << get_ParameterValue(t) << endl; fflush(stdout); } diff --git a/SimulationRuntime/interactive/omi_ServiceInterface.h b/SimulationRuntime/interactive/omi_ServiceInterface.h index c46f278be25..c54768a544f 100644 --- a/SimulationRuntime/interactive/omi_ServiceInterface.h +++ b/SimulationRuntime/interactive/omi_ServiceInterface.h @@ -98,9 +98,9 @@ void fillSimDataNames_AND_SimDataNamesFilter_WithValuesFromGlobalData( * Calls the "read_input_xml(...)" function from "simulation_input.cpp" and stores the simulation start data into * a set of variables from "omi_Calculation.cpp" */ -void getSimulationStartData(double*, long*, double*, string*, string*); - -int callSolverFromOM(string, string, double, double, double, long, double); +int intializeSolverStartData(double *stepSize, long *outputSteps, double *tolerance, string* method, string* outputFormat); +int performSolverStepFromOM(double start, double stop, double stepSize); +void deintializeSolverStartData(void); bool denied_work_on_GD(); bool allow_work_on_GD();