static void fmtEmitStep(DATA* data, threadData_t *threadData, MEASURE_TIME* mt, int didEventStep) { if(mt->fmtReal) { int i, flag=1; double tmpdbl; unsigned int tmpint; int total = data->modelData->modelDataXml.nFunctions + data->modelData->modelDataXml.nProfileBlocks; rt_tick(SIM_TIMER_OVERHEAD); rt_accumulate(SIM_TIMER_STEP); /* Disable time measurements if we have trouble writing to the file... */ flag = flag && 1 == fwrite(&mt->stepNo, sizeof(unsigned int), 1, mt->fmtInt); mt->stepNo++; flag = flag && 1 == fwrite(&(data->localData[0]->timeValue), sizeof(double), 1, mt->fmtReal); tmpdbl = rt_accumulated(SIM_TIMER_STEP); flag = flag && 1 == fwrite(&tmpdbl, sizeof(double), 1, mt->fmtReal); flag = flag && total == fwrite(rt_ncall_arr(SIM_TIMER_FIRST_FUNCTION), sizeof(uint32_t), total, mt->fmtInt); for(i=0; i<data->modelData->modelDataXml.nFunctions + data->modelData->modelDataXml.nProfileBlocks; i++) { tmpdbl = rt_accumulated(i + SIM_TIMER_FIRST_FUNCTION); flag = flag && 1 == fwrite(&tmpdbl, sizeof(double), 1, mt->fmtReal); } rt_accumulate(SIM_TIMER_OVERHEAD); if(!flag) { warningStreamPrint(LOG_SOLVER, 0, "Disabled time measurements because the output file could not be generated: %s", strerror(errno)); fclose(mt->fmtInt); fclose(mt->fmtReal); mt->fmtInt = NULL; mt->fmtReal = NULL; } } /* prevent emit if noEventEmit flag is used, if it's an event */ if ((omc_flag[FLAG_NOEVENTEMIT] && didEventStep == 0) || !omc_flag[FLAG_NOEVENTEMIT]) { sim_result.emit(&sim_result, data, threadData); } #if !defined(OMC_MINIMAL_RUNTIME) embedded_server_update(data->embeddedServerState, data->localData[0]->timeValue); if (data->real_time_sync.enabled) { double time = data->localData[0]->timeValue; int64_t res = rt_ext_tp_sync_nanosec(&data->real_time_sync.clock, (uint64_t) (data->real_time_sync.scaling*(time-data->real_time_sync.time)*1e9)); int64_t maxLateNano = data->simulationInfo->stepSize*1e9*0.1*data->real_time_sync.scaling /* Maximum late time: 10% of step size */; if (res > maxLateNano) { int t=0,tMaxLate=0; const char *unit = prettyPrintNanoSec(res, &t); const char *unit2 = prettyPrintNanoSec(maxLateNano, &tMaxLate); errorStreamPrint(LOG_RT, 0, "Missed deadline at time %g; delta was %d %s (maxLate=%d %s)", time, t, unit, tMaxLate, unit2); } if (res > data->real_time_sync.maxLate) { data->real_time_sync.maxLate = res; } } printAllVarsDebug(data, 0, LOG_DEBUG); /* ??? */ #endif }
static void fmtEmitStep(DATA* data, threadData_t *threadData, MEASURE_TIME* mt, int didEventStep) { if(mt->fmtReal) { int i, flag=1; double tmpdbl; unsigned int tmpint; int total = data->modelData.modelDataXml.nFunctions + data->modelData.modelDataXml.nProfileBlocks; rt_tick(SIM_TIMER_OVERHEAD); rt_accumulate(SIM_TIMER_STEP); /* Disable time measurements if we have trouble writing to the file... */ flag = flag && 1 == fwrite(&mt->stepNo, sizeof(unsigned int), 1, mt->fmtInt); mt->stepNo++; flag = flag && 1 == fwrite(&(data->localData[0]->timeValue), sizeof(double), 1, mt->fmtReal); tmpdbl = rt_accumulated(SIM_TIMER_STEP); flag = flag && 1 == fwrite(&tmpdbl, sizeof(double), 1, mt->fmtReal); flag = flag && total == fwrite(rt_ncall_arr(SIM_TIMER_FIRST_FUNCTION), sizeof(uint32_t), total, mt->fmtInt); for(i=0; i<data->modelData.modelDataXml.nFunctions + data->modelData.modelDataXml.nProfileBlocks; i++) { tmpdbl = rt_accumulated(i + SIM_TIMER_FIRST_FUNCTION); flag = flag && 1 == fwrite(&tmpdbl, sizeof(double), 1, mt->fmtReal); } rt_accumulate(SIM_TIMER_OVERHEAD); if(!flag) { warningStreamPrint(LOG_SOLVER, 0, "Disabled time measurements because the output file could not be generated: %s", strerror(errno)); fclose(mt->fmtInt); fclose(mt->fmtReal); mt->fmtInt = NULL; mt->fmtReal = NULL; } } /* prevent emit if noEventEmit flag is used, if it's an event */ if ((omc_flag[FLAG_NOEVENTEMIT] && didEventStep == 0) || !omc_flag[FLAG_NOEVENTEMIT]) { sim_result.emit(&sim_result, data, threadData); } printAllVarsDebug(data, 0, LOG_DEBUG); /* ??? */ }
/*! \fn performSimulation(DATA* data, SOLVER_INFO* solverInfo) * * \param [ref] [data] * \param [ref] [solverInfo] * * This function performs the simulation controlled by solverInfo. */ int prefixedName_performSimulation(DATA* data, threadData_t *threadData, SOLVER_INFO* solverInfo) { TRACE_PUSH int retValIntegrator=0; int retValue=0; int i, retry=0; unsigned int __currStepNo = 0; SIMULATION_INFO *simInfo = &(data->simulationInfo); solverInfo->currentTime = simInfo->startTime; MEASURE_TIME fmt; fmtInit(data, &fmt); printAllVarsDebug(data, 0, LOG_DEBUG); /* ??? */ printSparseStructure(data, LOG_SOLVER); modelica_boolean syncStep = 0; /***** Start main simulation loop *****/ while(solverInfo->currentTime < simInfo->stopTime) { int success = 0; threadData->currentErrorStage = ERROR_SIMULATION; #ifdef USE_DEBUG_TRACE if(useStream[LOG_TRACE]) printf("TRACE: push loop step=%u, time=%.12g\n", __currStepNo, solverInfo->currentTime); #endif omc_alloc_interface.collect_a_little(); /* try */ #if !defined(OMC_EMCC) MMC_TRY_INTERNAL(simulationJumpBuffer) #endif { clear_rt_step(data); rotateRingBuffer(data->simulationData, 1, (void**) data->localData); modelica_boolean syncEventStep = solverInfo->didEventStep || syncStep; /***** Calculation next step size *****/ if(syncEventStep) { infoStreamPrint(LOG_SOLVER, 0, "offset value for the next step: %.16g", (solverInfo->currentTime - solverInfo->laststep)); } else { if (solverInfo->solverNoEquidistantGrid) { if (solverInfo->currentTime >= solverInfo->lastdesiredStep) { double tmpTime = solverInfo->currentTime; do { __currStepNo++; solverInfo->currentStepSize = (double)(__currStepNo*(simInfo->stopTime-simInfo->startTime))/(simInfo->numSteps) + simInfo->startTime - solverInfo->currentTime; }while(solverInfo->currentStepSize <= 0); } } else { __currStepNo++; } } solverInfo->currentStepSize = (double)(__currStepNo*(simInfo->stopTime-simInfo->startTime))/(simInfo->numSteps) + simInfo->startTime - solverInfo->currentTime; solverInfo->lastdesiredStep = solverInfo->currentTime + solverInfo->currentStepSize; /* if retry reduce stepsize */ if(0 != retry) { solverInfo->currentStepSize /= 2; } /***** End calculation next step size *****/ checkForSynchronous(data, solverInfo); /* check for next time event */ checkForSampleEvent(data, solverInfo); /* if regular output point and last time events are almost equals * skip that step and go further */ if (solverInfo->currentStepSize < 1e-15 && syncEventStep){ __currStepNo++; continue; } /* * integration step determine all states by a integration method * update continuous system */ retValIntegrator = simulationStep(data, threadData, solverInfo); if (S_OPTIMIZATION == solverInfo->solverMethod) break; syncStep = simulationUpdate(data, threadData, solverInfo); retry = 0; /* reset retry */ fmtEmitStep(data, threadData, &fmt, solverInfo->didEventStep); saveDasslStats(solverInfo); checkSimulationTerminated(data, solverInfo); /* terminate for some cases: * - integrator fails * - non-linear system failed to solve * - assert was called */ if(retValIntegrator) { retValue = -1 + retValIntegrator; infoStreamPrint(LOG_STDOUT, 0, "model terminate | Integrator failed. | Simulation terminated at time %g", solverInfo->currentTime); break; } else if(check_nonlinear_solutions(data, 0)) { retValue = -2; infoStreamPrint(LOG_STDOUT, 0, "model terminate | non-linear system solver failed. | Simulation terminated at time %g", solverInfo->currentTime); break; } else if(check_linear_solutions(data, 0)) { retValue = -3; infoStreamPrint(LOG_STDOUT, 0, "model terminate | linear system solver failed. | Simulation terminated at time %g", solverInfo->currentTime); break; } else if(check_mixed_solutions(data, 0)) { retValue = -4; infoStreamPrint(LOG_STDOUT, 0, "model terminate | mixed system solver failed. | Simulation terminated at time %g", solverInfo->currentTime); break; } success = 1; } #if !defined(OMC_EMCC) MMC_CATCH_INTERNAL(simulationJumpBuffer) #endif if (!success) /* catch */ { if(0 == retry) { retrySimulationStep(data, threadData, solverInfo); retry = 1; } else { retValue = -1; infoStreamPrint(LOG_STDOUT, 0, "model terminate | Simulation terminated by an assert at time: %g", data->localData[0]->timeValue); break; } } TRACE_POP /* pop loop */ } /* end while solver */ fmtClose(&fmt); TRACE_POP return retValue; }
/*! \fn performSimulation(DATA* data, SOLVER_INFO* solverInfo) * * \param [ref] [data] * \param [ref] [solverInfo] * * This function performs the simulation controlled by solverInfo. */ int prefixedName_performSimulation(DATA* data, threadData_t *threadData, SOLVER_INFO* solverInfo) { TRACE_PUSH int retValIntegrator=0; int retValue=0; int i, retry=0, steadStateReached=0; unsigned int __currStepNo = 0; SIMULATION_INFO *simInfo = data->simulationInfo; solverInfo->currentTime = simInfo->startTime; MEASURE_TIME fmt; fmtInit(data, &fmt); printAllVarsDebug(data, 0, LOG_DEBUG); /* ??? */ if (!compiledInDAEMode) { printSparseStructure(&(data->simulationInfo->analyticJacobians[data->callback->INDEX_JAC_A].sparsePattern), data->simulationInfo->analyticJacobians[data->callback->INDEX_JAC_A].sizeRows, data->simulationInfo->analyticJacobians[data->callback->INDEX_JAC_A].sizeCols, LOG_SOLVER, "ODE sparse pattern"); } else { printSparseStructure(data->simulationInfo->daeModeData->sparsePattern, data->simulationInfo->daeModeData->nResidualVars, data->simulationInfo->daeModeData->nResidualVars, LOG_SOLVER, "DAE sparse pattern"); } if(terminationTerminate) { printInfo(stdout, TermInfo); fputc('\n', stdout); infoStreamPrint(LOG_STDOUT, 0, "Simulation call terminate() at initialization (time %f)\nMessage : %s", data->localData[0]->timeValue, TermMsg); data->simulationInfo->stopTime = solverInfo->currentTime; } else { modelica_boolean syncStep = 0; /***** Start main simulation loop *****/ while(solverInfo->currentTime < simInfo->stopTime || !simInfo->useStopTime) { int success = 0; threadData->currentErrorStage = ERROR_SIMULATION; #ifdef USE_DEBUG_TRACE if(useStream[LOG_TRACE]) { printf("TRACE: push loop step=%u, time=%.12g\n", __currStepNo, solverInfo->currentTime); } #endif /* check for steady state */ if (omc_flag[FLAG_STEADY_STATE]) { if (0 < data->modelData->nStates) { int i; double maxDer = 0.0; double currDer; for(i=data->modelData->nStates; i<2*data->modelData->nStates; ++i) { currDer = fabs(data->localData[0]->realVars[i] / data->modelData->realVarsData[i].attribute.nominal); if(maxDer < currDer) maxDer = currDer; } if (maxDer < steadyStateTol) { steadStateReached=1; infoStreamPrint(LOG_STDOUT, 0, "steady state reached at time = %g\n * max(|d(x_i)/dt|/nominal(x_i)) = %g\n * relative tolerance = %g", solverInfo->currentTime, maxDer, steadyStateTol); break; } } else throwStreamPrint(threadData, "No states in model. Flag -steadyState can only be used if states are present."); } omc_alloc_interface.collect_a_little(); /* try */ #if !defined(OMC_EMCC) MMC_TRY_INTERNAL(simulationJumpBuffer) #endif { printAllVars(data, 0, LOG_SOLVER_V); clear_rt_step(data); if (!compiledInDAEMode) /* do not use ringbuffer for daeMode */ rotateRingBuffer(data->simulationData, 1, (void**) data->localData); modelica_boolean syncEventStep = solverInfo->didEventStep || syncStep; /***** Calculation next step size *****/ if(syncEventStep) { infoStreamPrint(LOG_SOLVER, 0, "offset value for the next step: %.16g", (solverInfo->currentTime - solverInfo->laststep)); } else { if (solverInfo->solverNoEquidistantGrid) { if (solverInfo->currentTime >= solverInfo->lastdesiredStep) { do { __currStepNo++; solverInfo->currentStepSize = (double)(__currStepNo*(simInfo->stopTime-simInfo->startTime))/(simInfo->numSteps) + simInfo->startTime - solverInfo->currentTime; } while(solverInfo->currentStepSize <= 0); } } else { __currStepNo++; } } solverInfo->currentStepSize = (double)(__currStepNo*(simInfo->stopTime-simInfo->startTime))/(simInfo->numSteps) + simInfo->startTime - solverInfo->currentTime; solverInfo->lastdesiredStep = solverInfo->currentTime + solverInfo->currentStepSize; /* if retry reduce stepsize */ if (0 != retry) { solverInfo->currentStepSize /= 2; } /***** End calculation next step size *****/ checkForSynchronous(data, solverInfo); /* check for next time event */ checkForSampleEvent(data, solverInfo); /* if regular output point and last time events are almost equals * skip that step and go further */ if (solverInfo->currentStepSize < 1e-15 && syncEventStep){ __currStepNo++; continue; } /* * integration step determine all states by a integration method * update continuous system */ infoStreamPrint(LOG_SOLVER, 1, "call solver from %g to %g (stepSize: %.15g)", solverInfo->currentTime, solverInfo->currentTime + solverInfo->currentStepSize, solverInfo->currentStepSize); retValIntegrator = simulationStep(data, threadData, solverInfo); infoStreamPrint(LOG_SOLVER, 0, "finished solver step %g", solverInfo->currentTime); messageClose(LOG_SOLVER); if (S_OPTIMIZATION == solverInfo->solverMethod) break; syncStep = simulationUpdate(data, threadData, solverInfo); retry = 0; /* reset retry */ fmtEmitStep(data, threadData, &fmt, solverInfo); saveIntegratorStats(solverInfo); checkSimulationTerminated(data, solverInfo); /* terminate for some cases: * - integrator fails * - non-linear system failed to solve * - assert was called */ if (retValIntegrator) { retValue = -1 + retValIntegrator; infoStreamPrint(LOG_STDOUT, 0, "model terminate | Integrator failed. | Simulation terminated at time %g", solverInfo->currentTime); break; } else if(check_nonlinear_solutions(data, 0)) { retValue = -2; infoStreamPrint(LOG_STDOUT, 0, "model terminate | non-linear system solver failed. | Simulation terminated at time %g", solverInfo->currentTime); break; } else if(check_linear_solutions(data, 0)) { retValue = -3; infoStreamPrint(LOG_STDOUT, 0, "model terminate | linear system solver failed. | Simulation terminated at time %g", solverInfo->currentTime); break; } else if(check_mixed_solutions(data, 0)) { retValue = -4; infoStreamPrint(LOG_STDOUT, 0, "model terminate | mixed system solver failed. | Simulation terminated at time %g", solverInfo->currentTime); break; } success = 1; } #if !defined(OMC_EMCC) MMC_CATCH_INTERNAL(simulationJumpBuffer) #endif if (!success) { /* catch */ if(0 == retry) { retrySimulationStep(data, threadData, solverInfo); retry = 1; } else { retValue = -1; infoStreamPrint(LOG_STDOUT, 0, "model terminate | Simulation terminated by an assert at time: %g", data->localData[0]->timeValue); break; } } TRACE_POP /* pop loop */ } /* end while solver */ } /* end else */ fmtClose(&fmt); if (omc_flag[FLAG_STEADY_STATE] && !steadStateReached) { warningStreamPrint(LOG_STDOUT, 0, "Steady state has not been reached.\nThis may be due to too restrictive relative tolerance (%g) or short stopTime (%g).", steadyStateTol, simInfo->stopTime); } TRACE_POP return retValue; }