static int simulationUpdate(DATA* data, threadData_t *threadData, SOLVER_INFO* solverInfo)
{
  prefixedName_updateContinuousSystem(data, threadData);

  if (solverInfo->solverMethod == S_SYM_IMP_EULER) data->callback->symEulerUpdate(data, solverInfo->solverStepSize);

  saveZeroCrossings(data, threadData);
  messageClose(LOG_SOLVER);

  /***** Event handling *****/
  if (measure_time_flag) rt_tick(SIM_TIMER_EVENT);

  int syncRet = handleTimers(data, threadData, solverInfo);
  int syncRet1;
  do
  {
    int eventType = checkEvents(data, threadData, solverInfo->eventLst, &(solverInfo->currentTime), solverInfo);
    if(eventType > 0 || syncRet == 2) /* event */
    {
      threadData->currentErrorStage = ERROR_EVENTHANDLING;
      infoStreamPrint(LOG_EVENTS, 1, "%s event at time=%.12g", eventType == 1 ? "time" : "state", solverInfo->currentTime);
      /* prevent emit if noEventEmit flag is used */
      if (!(omc_flag[FLAG_NOEVENTEMIT])) /* output left limit */
        sim_result.emit(&sim_result, data, threadData);
      handleEvents(data, threadData, solverInfo->eventLst, &(solverInfo->currentTime), solverInfo);
      messageClose(LOG_EVENTS);
      threadData->currentErrorStage = ERROR_SIMULATION;

      solverInfo->didEventStep = 1;
      overwriteOldSimulationData(data);
    }
    else /* no event */
    {
      solverInfo->laststep = solverInfo->currentTime;
      solverInfo->didEventStep = 0;
    }

    if (measure_time_flag) rt_accumulate(SIM_TIMER_EVENT);
    /***** End event handling *****/


    /***** check state selection *****/
    if (stateSelection(data, threadData, 1, 1))
    {
      /* if new set is calculated reinit the solver */
      solverInfo->didEventStep = 1;
      overwriteOldSimulationData(data);
    }

    /* Check for warning of variables out of range assert(min<x || x>xmax, ...)*/
    data->callback->checkForAsserts(data, threadData);

    storePreValues(data);
    storeOldValues(data);

    syncRet1 = handleTimers(data, threadData, solverInfo);
    syncRet = syncRet1 == 0 ? syncRet : syncRet1;
  } while (syncRet1);
  return syncRet;
}
Beispiel #2
0
/*! \fn copyStartValuestoInitValues
 *
 *  Function to copy all start values to initial values
 *
 *  \param [ref] [data]
 */
void copyStartValuestoInitValues(DATA *data)
{
    TRACE_PUSH

    /* just copy all start values to initial */
    setAllParamsToStart(data);
    setAllVarsToStart(data);
    storePreValues(data);
    overwriteOldSimulationData(data);

    TRACE_POP
}
Beispiel #3
0
/*! \fn updateDiscreteSystem
 *
 *  Function to update the whole system with event iteration.
 *  Evaluates functionDAE()
 *
 *  \param [ref] [data]
 */
void updateDiscreteSystem(DATA *data, threadData_t *threadData)
{
    TRACE_PUSH
    int IterationNum = 0;
    int discreteChanged = 0;
    modelica_boolean relationChanged = 0;
    data->simulationInfo.needToIterate = 0;

    data->simulationInfo.callStatistics.updateDiscreteSystem++;

    data->callback->function_updateRelations(data, threadData, 1);
    updateRelationsPre(data);
    storeRelations(data);

    data->callback->functionDAE(data, threadData);
    debugStreamPrint(LOG_EVENTS_V, 0, "updated discrete System");

    relationChanged = checkRelations(data);
    discreteChanged = data->callback->checkForDiscreteChanges(data, threadData);
    while(discreteChanged || data->simulationInfo.needToIterate || relationChanged)
    {
        if(data->simulationInfo.needToIterate) {
            debugStreamPrint(LOG_EVENTS_V, 0, "reinit() call. Iteration needed!");
        }
        if(relationChanged) {
            debugStreamPrint(LOG_EVENTS_V, 0, "relations changed. Iteration needed.");
        }
        if(discreteChanged) {
            debugStreamPrint(LOG_EVENTS_V, 0, "discrete Variable changed. Iteration needed.");
        }

        storePreValues(data);
        updateRelationsPre(data);

        printRelations(data, LOG_EVENTS_V);
        printZeroCrossings(data, LOG_EVENTS_V);

        data->callback->functionDAE(data, threadData);

        IterationNum++;
        if(IterationNum > IterationMax) {
            throwStreamPrint(threadData, "ERROR: Too many event iterations. System is inconsistent. Simulation terminate.");
        }

        relationChanged = checkRelations(data);
        discreteChanged = data->callback->checkForDiscreteChanges(data, threadData);
    }
    storeRelations(data);

    TRACE_POP
}
/*! \fn updateContinuousSystem
 *
 *  Function to update the whole system with EventIteration.
 *  Evaluate the functionDAE()
 *
 *  \param [ref] [data]
 */
static void prefixedName_updateContinuousSystem(DATA *data, threadData_t *threadData)
{
  TRACE_PUSH

  externalInputUpdate(data);
  data->callback->input_function(data, threadData);
  data->callback->functionODE(data, threadData);
  data->callback->functionAlgebraics(data, threadData);
  data->callback->output_function(data, threadData);
  data->callback->function_storeDelayed(data, threadData);
  storePreValues(data);

  TRACE_POP
}
fmiStatus fmiCompletedIntegratorStep(fmiComponent c, fmiBoolean* callEventUpdate)
{
  ModelInstance* comp = (ModelInstance *)c;
  threadData_t *threadData = comp->threadData;
  if (invalidState(comp, "fmiCompletedIntegratorStep", modelInitialized))
    return fmiError;
  if (nullPointer(comp, "fmiCompletedIntegratorStep", "callEventUpdate", callEventUpdate))
    return fmiError;
  if (comp->loggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log",
      "fmiCompletedIntegratorStep");

  /* try */
  MMC_TRY_INTERNAL(simulationJumpBuffer)

    comp->fmuData->callback->functionAlgebraics(comp->fmuData, comp->threadData);
    comp->fmuData->callback->output_function(comp->fmuData, comp->threadData);
    comp->fmuData->callback->function_storeDelayed(comp->fmuData, comp->threadData);
    storePreValues(comp->fmuData);
    *callEventUpdate  = fmiFalse;
    /******** check state selection ********/
    if (stateSelection(comp->fmuData, comp->threadData, 1, 0))
    {
      if (comp->loggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log",
          "fmiEventUpdate: Need to iterate state values changed!");
      /* if new set is calculated reinit the solver */
      *callEventUpdate = fmiTrue;
    }
    /* TODO: fix the extrapolation in non-linear system
     *       then we can stop to save all variables in
     *       in the whole ringbuffer
     */
    overwriteOldSimulationData(comp->fmuData);
    return fmiOK;
  /* catch */
  MMC_CATCH_INTERNAL(simulationJumpBuffer)

  comp->functions.logger(c, comp->instanceName, fmiError, "error", "fmiCompletedIntegratorStep: terminated by an assertion.");
  return fmiError;
}
/*! \fn updateContinuousSystem
 *
 *  Function to update the whole system with EventIteration.
 *  Evaluate the functionDAE()
 *
 *  \param [ref] [data]
 */
static void prefixedName_updateContinuousSystem(DATA *data, threadData_t *threadData)
{
  TRACE_PUSH

  externalInputUpdate(data);
  data->callback->input_function(data, threadData);

  if (compiledInDAEMode) /* dae mode */
  {
    data->simulationInfo->daeModeData->evaluateDAEResiduals(data, threadData, EVAL_ALGEBRAIC);
  }
  else /* ode mode */
  {
    data->callback->functionODE(data, threadData);
    data->callback->functionAlgebraics(data, threadData);
  }
  data->callback->output_function(data, threadData);
  data->callback->setc_function(data, threadData);
  data->callback->function_storeDelayed(data, threadData);
  storePreValues(data);

  TRACE_POP
}
static void fmtEmitStep(DATA* data, threadData_t *threadData, MEASURE_TIME* mt, SOLVER_INFO* solverInfo)
{
  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] && solverInfo->didEventStep == 0) || !omc_flag[FLAG_NOEVENTEMIT]) {
    sim_result.emit(&sim_result, data, threadData);
  }
#if !defined(OMC_MINIMAL_RUNTIME)
  if (embedded_server_update(data->embeddedServerState, data->localData[0]->timeValue)) {
    solverInfo->didEventStep = 1;
    overwriteOldSimulationData(data);
    storePreValues(data); // Maybe??
    storeOldValues(data); // Maybe??
    sim_result.emit(&sim_result, data, threadData);
  }
  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
}
fmiStatus fmiEventUpdate(fmiComponent c, fmiBoolean intermediateResults, fmiEventInfo* eventInfo)
{
  int i;
  ModelInstance* comp = (ModelInstance *)c;
  threadData_t *threadData = comp->threadData;
  if (invalidState(comp, "fmiEventUpdate", modelInitialized))
    return fmiError;
  if (nullPointer(comp, "fmiEventUpdate", "eventInfo", eventInfo))
    return fmiError;
  eventInfo->stateValuesChanged = fmiFalse;

  if (comp->loggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log",
      "fmiEventUpdate: Start Event Update! Next Sample Event %g", eventInfo->nextEventTime);

  /* try */
  MMC_TRY_INTERNAL(simulationJumpBuffer)

    if (stateSelection(comp->fmuData, threadData, 1, 1))
    {
      if (comp->loggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log",
          "fmiEventUpdate: Need to iterate state values changed!");
      /* if new set is calculated reinit the solver */
      eventInfo->stateValuesChanged = fmiTrue;
    }

    storePreValues(comp->fmuData);

    /* activate sample event */
    for(i=0; i<comp->fmuData->modelData->nSamples; ++i)
    {
      if(comp->fmuData->simulationInfo->nextSampleTimes[i] <= comp->fmuData->localData[0]->timeValue)
      {
        comp->fmuData->simulationInfo->samples[i] = 1;
        infoStreamPrint(LOG_EVENTS, 0, "[%ld] sample(%g, %g)", comp->fmuData->modelData->samplesInfo[i].index, comp->fmuData->modelData->samplesInfo[i].start, comp->fmuData->modelData->samplesInfo[i].interval);
      }
    }

    comp->fmuData->callback->functionDAE(comp->fmuData, threadData);

    /* deactivate sample events */
    for(i=0; i<comp->fmuData->modelData->nSamples; ++i)
    {
      if(comp->fmuData->simulationInfo->samples[i])
      {
        comp->fmuData->simulationInfo->samples[i] = 0;
        comp->fmuData->simulationInfo->nextSampleTimes[i] += comp->fmuData->modelData->samplesInfo[i].interval;
      }
    }

    for(i=0; i<comp->fmuData->modelData->nSamples; ++i)
      if((i == 0) || (comp->fmuData->simulationInfo->nextSampleTimes[i] < comp->fmuData->simulationInfo->nextSampleEvent))
        comp->fmuData->simulationInfo->nextSampleEvent = comp->fmuData->simulationInfo->nextSampleTimes[i];

    if(comp->fmuData->callback->checkForDiscreteChanges(comp->fmuData, threadData) || comp->fmuData->simulationInfo->needToIterate || checkRelations(comp->fmuData) || eventInfo->stateValuesChanged)
    {
      intermediateResults = fmiTrue;
      if (comp->loggingOn)
        comp->functions.logger(c, comp->instanceName, fmiOK, "log", "fmiEventUpdate: Need to iterate(discrete changes)!");
      eventInfo->iterationConverged  = fmiTrue;
      eventInfo->stateValueReferencesChanged = fmiFalse;
      eventInfo->stateValuesChanged  = fmiTrue;
      eventInfo->terminateSimulation = fmiFalse;
    }
    else
    {
      intermediateResults = fmiFalse;
      eventInfo->iterationConverged  = fmiTrue;
      eventInfo->stateValueReferencesChanged = fmiFalse;
      eventInfo->terminateSimulation = fmiFalse;
    }

    /* due to an event overwrite old values */
    overwriteOldSimulationData(comp->fmuData);

    /* TODO: check the event iteration for relation
     * in fmi import and export. This is an workaround,
     * since the iteration seem not starting.
     */
    storePreValues(comp->fmuData);
    updateRelationsPre(comp->fmuData);

    if (comp->loggingOn)
      comp->functions.logger(c, comp->instanceName, fmiOK, "log", "fmiEventUpdate: intermediateResults = %d", intermediateResults);

    //Get Next Event Time
    double nextSampleEvent=0;
    nextSampleEvent = getNextSampleTimeFMU(comp->fmuData);
    if (nextSampleEvent == -1)
    {
      eventInfo->upcomingTimeEvent = fmiFalse;
    }
    else
    {
      eventInfo->upcomingTimeEvent = fmiTrue;
      eventInfo->nextEventTime = nextSampleEvent;
    }
    if (comp->loggingOn)
      comp->functions.logger(c, comp->instanceName, fmiOK, "log", "fmiEventUpdate: Checked for Sample Events! Next Sample Event %g",eventInfo->nextEventTime);

    return fmiOK;

  /* catch */
  MMC_CATCH_INTERNAL(simulationJumpBuffer)

  comp->functions.logger(c, comp->instanceName, fmiError, "error", "fmiEventUpdate: terminated by an assertion.");
  return fmiError;
}
Beispiel #9
0
/*! \fn static int symbolic_initialization(DATA *data)
 *
 *  \param [ref] [data]
 *
 *  \author lochel
 */
static int symbolic_initialization(DATA *data, threadData_t *threadData, long numLambdaSteps)
{
  TRACE_PUSH
  long step;
  int retVal;

  /* initial sample and delay before initial the system */
  initDelay(data, data->simulationInfo->startTime);

  /* initialize all relations that are ZeroCrossings */
  storePreValues(data);
  overwriteOldSimulationData(data);

  if (data->callback->useHomotopy && numLambdaSteps > 1)
  {
    long i;
    char buffer[4096];
    FILE *pFile = NULL;

    modelica_real* realVars = (modelica_real*)calloc(data->modelData->nVariablesReal, sizeof(modelica_real));
    modelica_integer* integerVars = (modelica_integer*)calloc(data->modelData->nVariablesInteger, sizeof(modelica_integer));
    modelica_boolean* booleanVars = (modelica_boolean*)calloc(data->modelData->nVariablesBoolean, sizeof(modelica_boolean));
    modelica_string* stringVars = (modelica_string*) omc_alloc_interface.malloc_uncollectable(data->modelData->nVariablesString * sizeof(modelica_string));
    MODEL_DATA *mData = data->modelData;

    assertStreamPrint(threadData, 0 != realVars, "out of memory");
    assertStreamPrint(threadData, 0 != integerVars, "out of memory");
    assertStreamPrint(threadData, 0 != booleanVars, "out of memory");
    assertStreamPrint(threadData, 0 != stringVars, "out of memory");

    for(i=0; i<mData->nVariablesReal; ++i) {
      realVars[i] = mData->realVarsData[i].attribute.start;
    }
    for(i=0; i<mData->nVariablesInteger; ++i) {
      integerVars[i] = mData->integerVarsData[i].attribute.start;
    }
    for(i=0; i<mData->nVariablesBoolean; ++i) {
      booleanVars[i] = mData->booleanVarsData[i].attribute.start;
    }
    for(i=0; i<mData->nVariablesString; ++i) {
      stringVars[i] = mData->stringVarsData[i].attribute.start;
    }

    if(ACTIVE_STREAM(LOG_INIT))
    {
      sprintf(buffer, "%s_homotopy.csv", mData->modelFilePrefix);
      pFile = fopen(buffer, "wt");
      fprintf(pFile, "%s,", "lambda");
      for(i=0; i<mData->nVariablesReal; ++i)
        fprintf(pFile, "%s,", mData->realVarsData[i].info.name);
      fprintf(pFile, "\n");
    }

    infoStreamPrint(LOG_INIT, 1, "homotopy process");
    for(step=0; step<numLambdaSteps; ++step)
    {
      data->simulationInfo->lambda = ((double)step)/(numLambdaSteps-1);

      if(data->simulationInfo->lambda > 1.0) {
        data->simulationInfo->lambda = 1.0;
      }

      if(0 == step)
        data->callback->functionInitialEquations_lambda0(data, threadData);
      else
        data->callback->functionInitialEquations(data, threadData);

      infoStreamPrint(LOG_INIT, 0, "lambda = %g done", data->simulationInfo->lambda);

      if(ACTIVE_STREAM(LOG_INIT))
      {
        fprintf(pFile, "%.16g,", data->simulationInfo->lambda);
        for(i=0; i<mData->nVariablesReal; ++i)
          fprintf(pFile, "%.16g,", data->localData[0]->realVars[i]);
        fprintf(pFile, "\n");
      }

      if(check_nonlinear_solutions(data, 0) ||
         check_linear_solutions(data, 0) ||
         check_mixed_solutions(data, 0))
        break;

      setAllStartToVars(data);
    }
    messageClose(LOG_INIT);

    if(ACTIVE_STREAM(LOG_INIT))
      fclose(pFile);

    for(i=0; i<mData->nVariablesReal; ++i)
      mData->realVarsData[i].attribute.start = realVars[i];
    for(i=0; i<mData->nVariablesInteger; ++i)
      mData->integerVarsData[i].attribute.start = integerVars[i];
    for(i=0; i<mData->nVariablesBoolean; ++i)
      mData->booleanVarsData[i].attribute.start = booleanVars[i];
    for(i=0; i<mData->nVariablesString; ++i)
      mData->stringVarsData[i].attribute.start = stringVars[i];

    free(realVars);
    free(integerVars);
    free(booleanVars);
    omc_alloc_interface.free_uncollectable(stringVars);
  }
  else
  {
    data->simulationInfo->lambda = 1.0;
    data->callback->functionInitialEquations(data, threadData);
  }
  storeRelations(data);

  /* check for over-determined systems */
  retVal = data->callback->functionRemovedInitialEquations(data, threadData);

  TRACE_POP
  return retVal;
}