Beispiel #1
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 solve mixed system with extended search
 *
 *  \param [in]  [data]
 *                [sysNumber] index of the corresponing mixed system
 *
 *  \author wbraun
 */
int solveMixedSearch(DATA *data, int sysNumber)
{
  MIXED_SYSTEM_DATA* systemData = &(data->simulationInfo->mixedSystemData[sysNumber]);
  DATA_SEARCHMIXED_SOLVER* solverData = (DATA_SEARCHMIXED_SOLVER*)systemData->solverData;

  int eqSystemNumber = systemData->equationIndex;

  int found_solution = 0;
  /*
   * We are given the number of the non-linear system.
   * We want to look it up among all equations.
   */
  int i, ix;

  int stepCount = 0;
  int mixedIterations = 0;
  int success = 0;

  debugStreamPrint(LOG_NLS, 1, "\n####  Start solver mixed equation system at time %f.", data->localData[0]->timeValue);

  memset(solverData->stateofSearch, 0, systemData->size);

  /* update pre iteration vars */
  /* update iteration vars */
  for(i=0;i<systemData->size;++i)
    solverData->iterationVarsPre[i] = *(systemData->iterationVarsPtr[i]);

  do
  {
    /* update pre iteration vars */
    for(i=0;i<systemData->size;++i)
      solverData->iterationVars[i] = *(systemData->iterationVarsPtr[i]);

    /* solve continuous equation part
     * and update iteration variables in model
     */
    systemData->solveContinuousPart(data);
    systemData->updateIterationExps(data);

    /* set new values of boolean variable */
    for(i=0;i<systemData->size;++i)
      solverData->iterationVars2[i] = *(systemData->iterationVarsPtr[i]);


    found_solution = systemData->continuous_solution;
    debugStreamPrint(LOG_NLS, 0, "####  continuous system solution status = %d", found_solution);

    /* restart if any relation has changed */
    if(checkRelations(data))
    {
      updateRelationsPre(data);
      systemData->updateIterationExps(data);
      debugStreamPrint(LOG_NLS, 0, "#### System relation changed restart iteration");
      if(mixedIterations++ > 200)
        found_solution = -4; /* mixedIterations++ > 200 */
    }

    if(found_solution == -1)
    {
      /* system of equations failed */
      found_solution = -2;
      debugStreamPrint(LOG_NLS, 0, "####  NO SOLUTION ");
    }
    else
    {
      found_solution = 1;
      for(i = 0; i < systemData->size; i++)
      {
        debugStreamPrint(LOG_NLS, 0, " check iterationVar[%d] = %d <-> %d", i, solverData->iterationVars[i], solverData->iterationVars2[i]);
        if(solverData->iterationVars[i] != solverData->iterationVars2[i])
        {
          found_solution  = 0;
          break;
        }
      }
      debugStreamPrint(LOG_NLS, 0, "#### SOLUTION = %c", found_solution  ? 'T' : 'F');
    }

    if(!found_solution )
    {
      /* try next set of values*/
      if(nextVar(solverData->stateofSearch, systemData->size))
      {
        debugStreamPrint(LOG_NLS, 0, "#### set next STATE ");
        for(i = 0; i < systemData->size; i++)
          *(systemData->iterationVarsPtr[i]) = *(systemData->iterationPreVarsPtr[i]) != solverData->stateofSearch[i];

        /* debug output */
        if(ACTIVE_STREAM(LOG_NLS))
        {
          const char * __name;
          for(i = 0; i < systemData->size; i++)
          {
            ix = (systemData->iterationVarsPtr[i]-data->localData[0]->booleanVars);
            __name = data->modelData->booleanVarsData[ix].info.name;
            debugStreamPrint(LOG_NLS, 0, "%s changed : %d -> %d", __name, solverData->iterationVars[i], *(systemData->iterationVarsPtr[i]));
          }
        }
      }
      else
      {
        /* while the initialization it's okay not a solution */
        if(!data->simulationInfo->initial)
        {
          warningStreamPrint(LOG_STDOUT, 0,
              "Error solving mixed equation system with index %d at time %e",
              eqSystemNumber, data->localData[0]->timeValue);
        }
        data->simulationInfo->needToIterate = 1;
        found_solution  = -1;
        /*TODO: "break simulation?"*/
      }
    }
    /* we found a solution*/
    if(found_solution  == 1)
    {
      success = 1;
      if(ACTIVE_STREAM(LOG_NLS))
      {
        const char * __name;
        debugStreamPrint(LOG_NLS, 0, "#### SOLUTION FOUND! (system %d)", eqSystemNumber);
        for(i = 0; i < systemData->size; i++)
        {
          ix = (systemData->iterationVarsPtr[i]-data->localData[0]->booleanVars);
          __name = data->modelData->booleanVarsData[ix].info.name;
          debugStreamPrint(LOG_NLS, 0, "%s = %d  pre(%s)= %d", __name, *systemData->iterationVarsPtr[i], __name,
              *systemData->iterationPreVarsPtr[i]);
        }
      }
    }

    stepCount++;
    mixedIterations++;

  }while(!found_solution);

  messageClose(LOG_NLS);
  debugStreamPrint(LOG_NLS, 0, "####  Finished mixed equation system in steps %d.\n", stepCount);
  return success;
}
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;
}