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;
}
Exemple #2
0
/******************************* interpolation module ************************************************/
int
interpolation_control(const int dideventstep, double interpolationStep,
                      double fixStep, double stop) {

  int i,l;
  if(sim_verbose >= LOG_SOLVER)
  {
    fprintf(stdout, "| info | dense output: $$$$$\t interpolate data at %g\n", interpolationStep); fflush(NULL);
  }
  /* if(sim_verbose >= LOG_SOLVER)
   * {
   *   cout << "oldTime,Time,interpolate data at " << globalData->oldTime << ", "
   *     << globalData->timeValue << ", " << interpolationStep << endl; fflush(NULL);
   * } /* for debugging */

  if(dideventstep == 1)
  {
    /* Emit data after an event */
    sim_result.emit(&sim_result,data);
  }

  if(((interpolationStep > globalData->oldTime) && (interpolationStep < globalData->timeValue)) ||
      ((dideventstep == 1) && (interpolationStep < globalData->timeValue)))
  {
    double** k = work_states;
    double backupTime = globalData->timeValue;
    double backupTime_old = globalData->oldTime;
    double* backupstats = (double*) malloc(globalData->nStates * sizeof(double));
    double* backupderivatives = (double*) malloc(globalData->nStates * sizeof(double));
    double* backupstats_old = (double*) malloc(globalData->nStates * sizeof(double));
    double bstar[9];
    double numerator = 0, sigma, sh, sum;

    /* save states and derivatives as they're altered by linear interpolation method */
    for(i = 0; i < globalData->nStates; i++)
    {
      backupstats[i] = globalData->states[i];
      backupderivatives[i] = globalData->statesDerivatives[i];
      backupstats_old[i] = globalData->states_old[i];
    }

    do
    {
      if(!(backupTime == backupTime_old)) /* don't interpolate during an event */
      {
        /* calculate dense output interpolation parameter sigma */
        sh = interpolationStep - globalData->timeValue;
        sigma = sh / globalData->current_stepsize;

        for(i = 0; i < dop5dense_s; i++)
        {
          /* compute bstar vector components using Horner's scheme */
          numerator = dop_bst[i][4] +
                      sigma * (dop_bst[i][3] +
                      sigma * (dop_bst[i][2] +
                      sigma * (dop_bst[i][1] +
                      sigma * dop_bst[i][0])));
          bstar[i] = numerator / dop_bst[i][5];
        }

        for(i = 0; i < globalData->nStates; i++)
        {
          sum = 0;
          for(l = 0; l < dop5dense_s; l++)
          {
            sum = sum + bstar[l] * k[l][i];
          }
          globalData->states[i] = globalData->states[i] + sh * sum;
        }

        /* set global time value to interpolated time */
        globalData->timeValue = interpolationStep;

        /* update all dependent variables */
        functionODE(NULL);
        functionAlgebraics(NULL);
        saveZeroCrossings();

        /* Emit interpolated data at the current time step */
        sim_result.emit(&sim_result,data);
      }

      interpolationStep = interpolationStep + fixStep;

    } while ((interpolationStep <= stop + fixStep) && (interpolationStep < backupTime));

    /* update old data */
    globalData->oldTime = backupTime;

    /* reset data for next solver step */
    globalData->timeValue = backupTime;
    for(i = 0; i < globalData->nStates; i++)
    {
      globalData->states[i] = backupstats[i];
      globalData->statesDerivatives[i] = backupderivatives[i];
    }

    free(backupstats);
    free(backupderivatives);
    free(backupstats_old);
  } else {
    globalData->oldTime = globalData->timeValue;
  }
  return 0;
}